From cc9de6b4b2301d20fb3ec97bcdbd2492122d8be4 Mon Sep 17 00:00:00 2001 From: Shish Date: Sat, 10 Feb 2024 23:03:14 +0000 Subject: [PATCH] [core] merge method-check and permission-check into page_matches() --- core/basethemelet.php | 9 - core/event.php | 35 ++- core/permissions.php | 2 +- core/userclass.php | 2 +- ext/admin/main.php | 33 +-- ext/admin/test.php | 12 +- ext/alias_editor/main.php | 58 ++-- ext/approval/main.php | 6 +- ext/artists/main.php | 543 +++++++++++++++-------------------- ext/auto_tagger/main.php | 58 ++-- ext/biography/main.php | 12 +- ext/blocks/main.php | 59 ++-- ext/blotter/main.php | 82 ++---- ext/blotter/test.php | 15 +- ext/bulk_actions/main.php | 2 +- ext/bulk_add/main.php | 12 +- ext/bulk_add_csv/main.php | 12 +- ext/comment/main.php | 209 ++++++-------- ext/et/main.php | 10 +- ext/favorites/main.php | 4 +- ext/featured/main.php | 18 +- ext/forum/main.php | 233 +++++++-------- ext/image/main.php | 20 +- ext/image_hash_ban/main.php | 54 ++-- ext/ipban/main.php | 50 ++-- ext/ipban/test.php | 6 +- ext/log_db/main.php | 10 +- ext/media/main.php | 2 +- ext/not_a_tag/main.php | 52 ++-- ext/notes/main.php | 232 ++++++++------- ext/numeric_score/main.php | 52 ++-- ext/pm/main.php | 99 +++---- ext/pools/main.php | 455 ++++++++++++++--------------- ext/private_image/main.php | 34 +-- ext/rating/main.php | 34 +-- ext/regen_thumb/main.php | 4 +- ext/replace_file/main.php | 8 +- ext/report_image/main.php | 31 +- ext/resize/main.php | 2 +- ext/rotate/main.php | 2 +- ext/s3/main.php | 5 +- ext/setup/main.php | 30 +- ext/setup/test.php | 12 +- ext/source_history/main.php | 12 +- ext/tag_categories/main.php | 10 +- ext/tag_edit/main.php | 22 +- ext/tag_history/main.php | 12 +- ext/tips/main.php | 58 ++-- ext/transcode/main.php | 2 +- ext/transcode_video/main.php | 2 +- ext/trash/main.php | 2 +- ext/update/main.php | 40 +-- ext/upload/main.php | 6 +- ext/user/main.php | 397 ++++++++++++------------- ext/user/test.php | 2 +- ext/user_config/main.php | 57 ++-- ext/user_config/test.php | 6 +- ext/view/main.php | 2 +- ext/wiki/main.php | 6 +- ext/wiki/test.php | 5 +- index.php | 10 +- 61 files changed, 1472 insertions(+), 1799 deletions(-) diff --git a/core/basethemelet.php b/core/basethemelet.php index ecfdd77b..f2b78a03 100644 --- a/core/basethemelet.php +++ b/core/basethemelet.php @@ -37,15 +37,6 @@ class BaseThemelet $page->add_block(new Block("Error", $message)); } - /** - * A specific, common error message - */ - public function display_permission_denied(): void - { - $this->display_error(403, "Permission Denied", "You do not have permission to access this page"); - } - - /** * Generic thumbnail code; returns HTML rather than adding * a block since thumbs tend to go inside blocks... diff --git a/core/event.php b/core/event.php index 1fa9b27d..df5e6949 100644 --- a/core/event.php +++ b/core/event.php @@ -59,6 +59,7 @@ class PageRequestEvent extends Event public array $args; public int $arg_count; public int $part_count; + public bool $is_authed; /** * @param string $method The HTTP method used to make the request @@ -68,6 +69,7 @@ class PageRequestEvent extends Event */ public function __construct(string $method, string $path, array $get, array $post) { + global $user; parent::__construct(); global $config; @@ -81,6 +83,7 @@ class PageRequestEvent extends Event $this->path = $path; $this->GET = $get; $this->POST = $post; + $this->is_authed = $user->check_auth_token(); // break the path into parts $args = explode('/', $path); @@ -163,28 +166,40 @@ class PageRequestEvent extends Event * * If it matches, store the remaining path elements in $args */ - public function page_matches(string $name): bool + public function page_matches(string $name, ?string $method = null, ?bool $authed = null, ?string $permission = null): bool { - $parts = explode("/", $name); - $this->part_count = count($parts); + global $user; - if ($this->part_count > $this->arg_count) { + assert($method === null || in_array($method, ["GET", "POST", "OPTIONS"])); + $authed = $authed ?? $method == "POST"; + + // method check is fast so do that first + if($method !== null && $this->method !== $method) { return false; } + // check if the path matches + $parts = explode("/", $name); + $this->part_count = count($parts); + if ($this->part_count > $this->arg_count) { + return false; + } for ($i = 0; $i < $this->part_count; $i++) { if ($parts[$i] != $this->args[$i]) { return false; } } - return true; - } + // if we matched the method and the path, but the page requires + // authentication and the user is not authenticated, then complain + if($authed && $this->is_authed === false) { + throw new PermissionDeniedException("Permission Denied"); + } + if($permission !== null && !$user->can($permission)) { + throw new PermissionDeniedException("Permission Denied"); + } - public function authed_page_matches(string $name): bool - { - global $user; - return $this->page_matches($name) && $user->check_auth_token(); + return true; } /** diff --git a/core/permissions.php b/core/permissions.php index 08b2556a..7e3981e8 100644 --- a/core/permissions.php +++ b/core/permissions.php @@ -88,7 +88,7 @@ abstract class Permissions public const BULK_EDIT_VOTE = "bulk_edit_vote"; public const EDIT_OTHER_VOTE = "edit_other_vote"; - public const VIEW_SYSINTO = "view_sysinfo"; + public const VIEW_SYSINFO = "view_sysinfo"; public const HELLBANNED = "hellbanned"; public const VIEW_HELLBANNED = "view_hellbanned"; diff --git a/core/userclass.php b/core/userclass.php index e9da051a..9716b060 100644 --- a/core/userclass.php +++ b/core/userclass.php @@ -188,7 +188,7 @@ new UserClass("admin", "base", [ Permissions::BULK_EDIT_VOTE => true, Permissions::EDIT_OTHER_VOTE => true, Permissions::CREATE_VOTE => true, - Permissions::VIEW_SYSINTO => true, + Permissions::VIEW_SYSINFO => true, Permissions::HELLBANNED => false, Permissions::VIEW_HELLBANNED => true, diff --git a/ext/admin/main.php b/ext/admin/main.php index 813fc5d2..cc4aeff9 100644 --- a/ext/admin/main.php +++ b/ext/admin/main.php @@ -49,29 +49,22 @@ class AdminPage extends Extension { global $database, $page, $user; - if ($event->page_matches("admin")) { - if (!$user->can(Permissions::MANAGE_ADMINTOOLS)) { - $this->theme->display_permission_denied(); + if ($event->page_matches("admin", permission: Permissions::MANAGE_ADMINTOOLS)) { + if ($event->count_args() == 0) { + send_event(new AdminBuildingEvent($page)); } else { - if ($event->count_args() == 0) { - send_event(new AdminBuildingEvent($page)); - } else { - $action = $event->get_arg(0); - $aae = new AdminActionEvent($action, $event->POST); + $action = $event->get_arg(0); + $aae = new AdminActionEvent($action, $event->POST); - if ($user->check_auth_token()) { - log_info("admin", "Util: $action"); - shm_set_timeout(null); - $database->set_timeout(null); - send_event($aae); - } else { - throw new SCoreException("Invalid CSRF token"); - } + $user->ensure_authed(); + log_info("admin", "Util: $action"); + shm_set_timeout(null); + $database->set_timeout(null); + send_event($aae); - if ($aae->redirect) { - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("admin")); - } + if ($aae->redirect) { + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("admin")); } } } diff --git a/ext/admin/test.php b/ext/admin/test.php index 6975d1e8..2bbd051e 100644 --- a/ext/admin/test.php +++ b/ext/admin/test.php @@ -9,14 +9,14 @@ class AdminPageTest extends ShimmiePHPUnitTestCase public function testAuth(): void { send_event(new UserLoginEvent(User::by_name(self::$anon_name))); - $page = $this->get_page('admin'); - $this->assertEquals(403, $page->code); - $this->assertEquals("Permission Denied", $page->title); + $this->assertException(PermissionDeniedException::class, function () { + $this->get_page('admin'); + }); send_event(new UserLoginEvent(User::by_name(self::$user_name))); - $page = $this->get_page('admin'); - $this->assertEquals(403, $page->code); - $this->assertEquals("Permission Denied", $page->title); + $this->assertException(PermissionDeniedException::class, function () { + $this->get_page('admin'); + }); send_event(new UserLoginEvent(User::by_name(self::$admin_name))); $page = $this->get_page('admin'); diff --git a/ext/alias_editor/main.php b/ext/alias_editor/main.php index 26bef9b3..02300dd6 100644 --- a/ext/alias_editor/main.php +++ b/ext/alias_editor/main.php @@ -66,27 +66,23 @@ class AliasEditor extends Extension global $config, $database, $page, $user; if ($event->page_matches("alias")) { - if ($event->get_arg(0) == "add") { - if ($user->can(Permissions::MANAGE_ALIAS_LIST)) { - $user->ensure_authed(); - $input = validate_input(["c_oldtag" => "string", "c_newtag" => "string"]); - try { - send_event(new AddAliasEvent($input['c_oldtag'], $input['c_newtag'])); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("alias/list")); - } catch (AddAliasException $ex) { - $this->theme->display_error(500, "Error adding alias", $ex->getMessage()); - } - } - } elseif ($event->get_arg(0) == "remove") { - if ($user->can(Permissions::MANAGE_ALIAS_LIST)) { - $user->ensure_authed(); - $input = validate_input(["d_oldtag" => "string"]); - send_event(new DeleteAliasEvent($input['d_oldtag'])); + if ($event->page_matches("alias/add", method: "POST", permission: Permissions::MANAGE_ALIAS_LIST)) { + $input = validate_input(["c_oldtag" => "string", "c_newtag" => "string"]); + try { + send_event(new AddAliasEvent($input['c_oldtag'], $input['c_newtag'])); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("alias/list")); + } catch (AddAliasException $ex) { + $this->theme->display_error(500, "Error adding alias", $ex->getMessage()); } - } elseif ($event->get_arg(0) == "list") { + } + if ($event->page_matches("alias/remove", method: "POST", permission: Permissions::MANAGE_ALIAS_LIST)) { + $input = validate_input(["d_oldtag" => "string"]); + send_event(new DeleteAliasEvent($input['d_oldtag'])); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("alias/list")); + } + if ($event->page_matches("alias/list")) { $t = new AliasTable($database->raw_db()); $t->token = $user->get_auth_token(); $t->inputs = $event->GET; @@ -96,25 +92,23 @@ class AliasEditor extends Extension $t->delete_url = make_link("alias/remove"); } $this->theme->display_aliases($t->table($t->query()), $t->paginator()); - } elseif ($event->get_arg(0) == "export") { + } + if ($event->page_matches("alias/export")) { $page->set_mode(PageMode::DATA); $page->set_mime(MimeType::CSV); $page->set_filename("aliases.csv"); $page->set_data($this->get_alias_csv($database)); - } elseif ($event->get_arg(0) == "import") { - if ($user->can(Permissions::MANAGE_ALIAS_LIST)) { - if (count($_FILES) > 0) { - $tmp = $_FILES['alias_file']['tmp_name']; - $contents = file_get_contents_ex($tmp); - $this->add_alias_csv($contents); - log_info("alias_editor", "Imported aliases from file", "Imported aliases"); # FIXME: how many? - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("alias/list")); - } else { - $this->theme->display_error(400, "No File Specified", "You have to upload a file"); - } + } + if ($event->page_matches("alias/import", method: "POST", permission: Permissions::MANAGE_ALIAS_LIST)) { + if (count($_FILES) > 0) { + $tmp = $_FILES['alias_file']['tmp_name']; + $contents = file_get_contents_ex($tmp); + $this->add_alias_csv($contents); + log_info("alias_editor", "Imported aliases from file", "Imported aliases"); # FIXME: how many? + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("alias/list")); } else { - $this->theme->display_error(401, "Admins Only", "Only admins can edit the alias list"); + $this->theme->display_error(400, "No File Specified", "You have to upload a file"); } } } diff --git a/ext/approval/main.php b/ext/approval/main.php index 2e129425..e030a205 100644 --- a/ext/approval/main.php +++ b/ext/approval/main.php @@ -40,16 +40,14 @@ class Approval extends Extension { global $page, $user; - if ($event->page_matches("approve_image") && $user->can(Permissions::APPROVE_IMAGE)) { - // Try to get the image ID + if ($event->page_matches("approve_image", method: "POST", permission: Permissions::APPROVE_IMAGE)) { $image_id = int_escape(null_throws($event->get_arg(0))); self::approve_image($image_id); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/" . $image_id)); } - if ($event->page_matches("disapprove_image") && $user->can(Permissions::APPROVE_IMAGE)) { - // Try to get the image ID + if ($event->page_matches("disapprove_image", method: "POST", permission: Permissions::APPROVE_IMAGE)) { $image_id = int_escape(null_throws($event->get_arg(0))); self::disapprove_image($image_id); $page->set_mode(PageMode::REDIRECT); diff --git a/ext/artists/main.php b/ext/artists/main.php index e1c259f7..850272e4 100644 --- a/ext/artists/main.php +++ b/ext/artists/main.php @@ -169,262 +169,182 @@ class Artists extends Extension { global $page, $user; - if ($event->page_matches("artist")) { - switch ($event->get_arg(0)) { - //*************ARTIST SECTION************** - case "list": - { - $this->get_listing($event); - $this->theme->sidebar_options("neutral"); - break; - } - case "new": - { - if (!$user->is_anonymous()) { - $this->theme->new_artist_composer(); - } else { - $this->theme->display_error(401, "Error", "You must be registered and logged in to create a new artist."); - } - break; - } - case "new_artist": - { - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/new")); - break; - } - case "create": - { - if (!$user->is_anonymous()) { - $newArtistID = $this->add_artist(); - if ($newArtistID == -1) { - $this->theme->display_error(400, "Error", "Error when entering artist data."); - } else { - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/view/".$newArtistID)); - } - } else { - $this->theme->display_error(401, "Error", "You must be registered and logged in to create a new artist."); - } - break; - } - - case "view": - { - $artistID = int_escape($event->get_arg(1)); - $artist = $this->get_artist($artistID); - $aliases = $this->get_alias($artist['id']); - $members = $this->get_members($artist['id']); - $urls = $this->get_urls($artist['id']); - - $userIsLogged = !$user->is_anonymous(); - $userIsAdmin = $user->can(Permissions::ARTISTS_ADMIN); - - $images = Search::find_images(limit: 4, tags: Tag::explode($artist['name'])); - - $this->theme->show_artist($artist, $aliases, $members, $urls, $images, $userIsLogged, $userIsAdmin); - /* - if ($userIsLogged) { - $this->theme->show_new_alias_composer($artistID); - $this->theme->show_new_member_composer($artistID); - $this->theme->show_new_url_composer($artistID); - } - */ - - $this->theme->sidebar_options("editor", $artistID, $userIsAdmin); - - break; - } - - case "edit": - { - $artistID = int_escape($event->get_arg(1)); - $artist = $this->get_artist($artistID); - $aliases = $this->get_alias($artistID); - $members = $this->get_members($artistID); - $urls = $this->get_urls($artistID); - - if (!$user->is_anonymous()) { - $this->theme->show_artist_editor($artist, $aliases, $members, $urls); - - $userIsAdmin = $user->can(Permissions::ARTISTS_ADMIN); - $this->theme->sidebar_options("editor", $artistID, $userIsAdmin); - } else { - $this->theme->display_error(401, "Error", "You must be registered and logged in to edit an artist."); - } - break; - } - case "edit_artist": - { - $artistID = int_escape($event->req_POST('artist_id')); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/edit/".$artistID)); - break; - } - case "edited": - { - $artistID = int_escape($event->get_POST('id')); - $this->update_artist(); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/view/".$artistID)); - break; - } - case "nuke_artist": - { - $artistID = int_escape($event->req_POST('artist_id')); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/nuke/".$artistID)); - break; - } - case "nuke": - { - $artistID = int_escape($event->get_arg(1)); - $this->delete_artist($artistID); // this will delete the artist, its alias, its urls and its members - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/list")); - break; - } - case "add_alias": - { - $artistID = int_escape($event->req_POST('artist_id')); - $this->theme->show_new_alias_composer($artistID); - break; - } - case "add_member": - { - $artistID = int_escape($event->req_POST('artist_id')); - $this->theme->show_new_member_composer($artistID); - break; - } - case "add_url": - { - $artistID = int_escape($event->req_POST('artist_id')); - $this->theme->show_new_url_composer($artistID); - break; - } - //***********ALIAS SECTION *********************** - case "alias": - { - switch ($event->get_arg(1)) { - case "add": - { - $artistID = int_escape($event->req_POST('artist_id')); - $this->add_alias(); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/view/".$artistID)); - break; - } - case "delete": - { - $aliasID = int_escape($event->get_arg(2)); - $artistID = $this->get_artistID_by_aliasID($aliasID); - $this->delete_alias($aliasID); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/view/".$artistID)); - break; - } - case "edit": - { - $aliasID = int_escape($event->get_arg(2)); - $alias = $this->get_alias_by_id($aliasID); - $this->theme->show_alias_editor($alias); - break; - } - case "edited": - { - $this->update_alias(); - $aliasID = int_escape($event->req_POST('aliasID')); - $artistID = $this->get_artistID_by_aliasID($aliasID); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/view/".$artistID)); - break; - } - } - break; // case: alias - } - - //**************** URLS SECTION ********************** - case "url": - { - switch ($event->get_arg(1)) { - case "add": - { - $artistID = int_escape($event->req_POST('artist_id')); - $this->add_urls(); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/view/".$artistID)); - break; - } - case "delete": - { - $urlID = int_escape($event->get_arg(2)); - $artistID = $this->get_artistID_by_urlID($urlID); - $this->delete_url($urlID); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/view/".$artistID)); - break; - } - case "edit": - { - $urlID = int_escape($event->get_arg(2)); - $url = $this->get_url_by_id($urlID); - $this->theme->show_url_editor($url); - break; - } - case "edited": - { - $this->update_url(); - $urlID = int_escape($event->req_POST('urlID')); - $artistID = $this->get_artistID_by_urlID($urlID); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/view/".$artistID)); - break; - } - } - break; // case: urls - } - //******************* MEMBERS SECTION ********************* - case "member": - { - switch ($event->get_arg(1)) { - case "add": - { - $artistID = int_escape($event->req_POST('artist_id')); - $this->add_members(); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/view/".$artistID)); - break; - } - case "delete": - { - $memberID = int_escape($event->get_arg(2)); - $artistID = $this->get_artistID_by_memberID($memberID); - $this->delete_member($memberID); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/view/".$artistID)); - break; - } - case "edit": - { - $memberID = int_escape($event->get_arg(2)); - $member = $this->get_member_by_id($memberID); - $this->theme->show_member_editor($member); - break; - } - case "edited": - { - $this->update_member(); - $memberID = int_escape($event->req_POST('memberID')); - $artistID = $this->get_artistID_by_memberID($memberID); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("artist/view/".$artistID)); - break; - } - } - break; //case: members - } + if ($event->page_matches("artist/list")) { + $this->get_listing(clamp(int_escape($event->get_arg(0)), 1, null) - 1); + $this->theme->sidebar_options("neutral"); + } + if ($event->page_matches("artist/new")) { + if (!$user->is_anonymous()) { + $this->theme->new_artist_composer(); + } else { + $this->theme->display_error(401, "Error", "You must be registered and logged in to create a new artist."); } } + if ($event->page_matches("artist/new_artist")) { + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/new")); + } + if ($event->page_matches("artist/create")) { + if (!$user->is_anonymous()) { + $newArtistID = $this->add_artist(); + if ($newArtistID == -1) { + $this->theme->display_error(400, "Error", "Error when entering artist data."); + } else { + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/view/" . $newArtistID)); + } + } else { + $this->theme->display_error(401, "Error", "You must be registered and logged in to create a new artist."); + } + } + if ($event->page_matches("artist/view")) { + $artistID = int_escape($event->get_arg(0)); + $artist = $this->get_artist($artistID); + $aliases = $this->get_alias($artist['id']); + $members = $this->get_members($artist['id']); + $urls = $this->get_urls($artist['id']); + + $userIsLogged = !$user->is_anonymous(); + $userIsAdmin = $user->can(Permissions::ARTISTS_ADMIN); + + $images = Search::find_images(limit: 4, tags: Tag::explode($artist['name'])); + + $this->theme->show_artist($artist, $aliases, $members, $urls, $images, $userIsLogged, $userIsAdmin); + /* + if ($userIsLogged) { + $this->theme->show_new_alias_composer($artistID); + $this->theme->show_new_member_composer($artistID); + $this->theme->show_new_url_composer($artistID); + } + */ + + $this->theme->sidebar_options("editor", $artistID, $userIsAdmin); + } + if ($event->page_matches("artist/edit")) { + $artistID = int_escape($event->get_arg(0)); + $artist = $this->get_artist($artistID); + $aliases = $this->get_alias($artistID); + $members = $this->get_members($artistID); + $urls = $this->get_urls($artistID); + + if (!$user->is_anonymous()) { + $this->theme->show_artist_editor($artist, $aliases, $members, $urls); + + $userIsAdmin = $user->can(Permissions::ARTISTS_ADMIN); + $this->theme->sidebar_options("editor", $artistID, $userIsAdmin); + } else { + $this->theme->display_error(401, "Error", "You must be registered and logged in to edit an artist."); + } + } + if ($event->page_matches("artist/edit_artist")) { + $artistID = int_escape($event->req_POST('artist_id')); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/edit/" . $artistID)); + } + if ($event->page_matches("artist/edited")) { + $artistID = int_escape($event->get_POST('id')); + $this->update_artist(); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/view/" . $artistID)); + } + if ($event->page_matches("artist/nuke_artist")) { + $artistID = int_escape($event->req_POST('artist_id')); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/nuke/" . $artistID)); + } + if ($event->page_matches("artist/nuke")) { + $artistID = int_escape($event->get_arg(0)); + $this->delete_artist($artistID); // this will delete the artist, its alias, its urls and its members + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/list")); + } + if ($event->page_matches("artist/add_alias")) { + $artistID = int_escape($event->req_POST('artist_id')); + $this->theme->show_new_alias_composer($artistID); + } + if ($event->page_matches("artist/add_member")) { + $artistID = int_escape($event->req_POST('artist_id')); + $this->theme->show_new_member_composer($artistID); + } + if ($event->page_matches("artist/add_url")) { + $artistID = int_escape($event->req_POST('artist_id')); + $this->theme->show_new_url_composer($artistID); + } + if ($event->page_matches("artist/alias/add")) { + $artistID = int_escape($event->req_POST('artist_id')); + $this->add_alias(); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/view/" . $artistID)); + } + if ($event->page_matches("artist/alias/delete")) { + $aliasID = int_escape($event->get_arg(0)); + $artistID = $this->get_artistID_by_aliasID($aliasID); + $this->delete_alias($aliasID); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/view/" . $artistID)); + } + if ($event->page_matches("artist/alias/edit")) { + $aliasID = int_escape($event->get_arg(0)); + $alias = $this->get_alias_by_id($aliasID); + $this->theme->show_alias_editor($alias); + } + if ($event->page_matches("artist/alias/edited")) { + $this->update_alias(); + $aliasID = int_escape($event->req_POST('aliasID')); + $artistID = $this->get_artistID_by_aliasID($aliasID); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/view/" . $artistID)); + } + if ($event->page_matches("artist/url/add")) { + $artistID = int_escape($event->req_POST('artist_id')); + $this->add_urls(); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/view/" . $artistID)); + } + if ($event->page_matches("artist/url/delete")) { + $urlID = int_escape($event->get_arg(0)); + $artistID = $this->get_artistID_by_urlID($urlID); + $this->delete_url($urlID); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/view/" . $artistID)); + } + if ($event->page_matches("artist/url/edit")) { + $urlID = int_escape($event->get_arg(0)); + $url = $this->get_url_by_id($urlID); + $this->theme->show_url_editor($url); + } + if ($event->page_matches("artist/url/edited")) { + $this->update_url(); + $urlID = int_escape($event->req_POST('urlID')); + $artistID = $this->get_artistID_by_urlID($urlID); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/view/" . $artistID)); + } + if ($event->page_matches("artist/member/add")) { + $artistID = int_escape($event->req_POST('artist_id')); + $this->add_members(); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/view/" . $artistID)); + } + if ($event->page_matches("artist/member/delete")) { + $memberID = int_escape($event->get_arg(0)); + $artistID = $this->get_artistID_by_memberID($memberID); + $this->delete_member($memberID); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/view/" . $artistID)); + } + if ($event->page_matches("artist/member/edit")) { + $memberID = int_escape($event->get_arg(0)); + $member = $this->get_member_by_id($memberID); + $this->theme->show_member_editor($member); + } + if ($event->page_matches("artist/member/edited")) { + $this->update_member(); + $memberID = int_escape($event->req_POST('memberID')); + $artistID = $this->get_artistID_by_memberID($memberID); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("artist/view/" . $artistID)); + } } private function get_artistName_by_imageID(int $imageID): string @@ -468,37 +388,37 @@ class Artists extends Extension private function get_artistID_by_url(string $url): int { global $database; - return (int)$database->get_one("SELECT artist_id FROM artist_urls WHERE url = :url", ['url' => $url]); + return (int) $database->get_one("SELECT artist_id FROM artist_urls WHERE url = :url", ['url' => $url]); } private function get_artistID_by_memberName(string $member): int { global $database; - return (int)$database->get_one("SELECT artist_id FROM artist_members WHERE name = :name", ['name' => $member]); + return (int) $database->get_one("SELECT artist_id FROM artist_members WHERE name = :name", ['name' => $member]); } private function get_artistName_by_artistID(int $artistID): string { global $database; - return (string)$database->get_one("SELECT name FROM artists WHERE id = :id", ['id' => $artistID]); + return (string) $database->get_one("SELECT name FROM artists WHERE id = :id", ['id' => $artistID]); } private function get_artistID_by_aliasID(int $aliasID): int { global $database; - return (int)$database->get_one("SELECT artist_id FROM artist_alias WHERE id = :id", ['id' => $aliasID]); + return (int) $database->get_one("SELECT artist_id FROM artist_alias WHERE id = :id", ['id' => $aliasID]); } private function get_artistID_by_memberID(int $memberID): int { global $database; - return (int)$database->get_one("SELECT artist_id FROM artist_members WHERE id = :id", ['id' => $memberID]); + return (int) $database->get_one("SELECT artist_id FROM artist_members WHERE id = :id", ['id' => $memberID]); } private function get_artistID_by_urlID(int $urlID): int { global $database; - return (int)$database->get_one("SELECT artist_id FROM artist_urls WHERE id = :id", ['id' => $urlID]); + return (int) $database->get_one("SELECT artist_id FROM artist_urls WHERE id = :id", ['id' => $urlID]); } private function delete_alias(int $aliasID): void @@ -818,7 +738,7 @@ class Artists extends Extension ); $num = count($result); - for ($i = 0 ; $i < $num ; $i++) { + for ($i = 0; $i < $num; $i++) { $result[$i]["name"] = stripslashes($result[$i]["name"]); } @@ -837,7 +757,7 @@ class Artists extends Extension ); $num = count($result); - for ($i = 0 ; $i < $num ; $i++) { + for ($i = 0; $i < $num; $i++) { $result[$i]["url"] = stripslashes($result[$i]["url"]); } @@ -847,7 +767,7 @@ class Artists extends Extension private function get_artist_id(string $name): int { global $database; - return (int)$database->get_one( + return (int) $database->get_one( "SELECT id FROM artists WHERE name = :name", ['name' => $name] ); @@ -857,7 +777,7 @@ class Artists extends Extension { global $database; - return (int)$database->get_one( + return (int) $database->get_one( "SELECT artist_id FROM artist_alias WHERE alias = :alias", ['alias' => $alias] ); @@ -873,60 +793,59 @@ class Artists extends Extension } /* - * HERE WE GET THE LIST OF ALL ARTIST WITH PAGINATION - */ - private function get_listing(PageRequestEvent $event): void + * HERE WE GET THE LIST OF ALL ARTIST WITH PAGINATION + */ + private function get_listing(int $pageNumber): void { global $config, $database; - $pageNumber = clamp(int_escape($event->get_arg(1)), 1, null) - 1; $artistsPerPage = $config->get_int("artistsPerPage"); $listing = $database->get_all( " - ( - SELECT a.id, a.user_id, a.name, u.name AS user_name, COALESCE(t.count, 0) AS posts - , 'artist' as type, a.id AS artist_id, a.name AS artist_name, a.updated - FROM artists AS a - INNER JOIN users AS u - ON a.user_id = u.id - LEFT OUTER JOIN tags AS t - ON a.name = t.tag - GROUP BY a.id, a.user_id, a.name, u.name - ORDER BY a.updated DESC - ) + ( + SELECT a.id, a.user_id, a.name, u.name AS user_name, COALESCE(t.count, 0) AS posts + , 'artist' as type, a.id AS artist_id, a.name AS artist_name, a.updated + FROM artists AS a + INNER JOIN users AS u + ON a.user_id = u.id + LEFT OUTER JOIN tags AS t + ON a.name = t.tag + GROUP BY a.id, a.user_id, a.name, u.name + ORDER BY a.updated DESC + ) - UNION + UNION - ( - SELECT aa.id, aa.user_id, aa.alias AS name, u.name AS user_name, COALESCE(t.count, 0) AS posts - , 'alias' as type, a.id AS artist_id, a.name AS artist_name, aa.updated - FROM artist_alias AS aa - INNER JOIN users AS u - ON aa.user_id = u.id - INNER JOIN artists AS a - ON aa.artist_id = a.id - LEFT OUTER JOIN tags AS t - ON aa.alias = t.tag - GROUP BY aa.id, a.user_id, aa.alias, u.name, a.id, a.name - ORDER BY aa.updated DESC - ) + ( + SELECT aa.id, aa.user_id, aa.alias AS name, u.name AS user_name, COALESCE(t.count, 0) AS posts + , 'alias' as type, a.id AS artist_id, a.name AS artist_name, aa.updated + FROM artist_alias AS aa + INNER JOIN users AS u + ON aa.user_id = u.id + INNER JOIN artists AS a + ON aa.artist_id = a.id + LEFT OUTER JOIN tags AS t + ON aa.alias = t.tag + GROUP BY aa.id, a.user_id, aa.alias, u.name, a.id, a.name + ORDER BY aa.updated DESC + ) - UNION + UNION - ( - SELECT m.id, m.user_id, m.name AS name, u.name AS user_name, COALESCE(t.count, 0) AS posts - , 'member' AS type, a.id AS artist_id, a.name AS artist_name, m.updated - FROM artist_members AS m - INNER JOIN users AS u - ON m.user_id = u.id - INNER JOIN artists AS a - ON m.artist_id = a.id - LEFT OUTER JOIN tags AS t - ON m.name = t.tag - GROUP BY m.id, m.user_id, m.name, u.name, a.id, a.name - ORDER BY m.updated DESC - ) + ( + SELECT m.id, m.user_id, m.name AS name, u.name AS user_name, COALESCE(t.count, 0) AS posts + , 'member' AS type, a.id AS artist_id, a.name AS artist_name, m.updated + FROM artist_members AS m + INNER JOIN users AS u + ON m.user_id = u.id + INNER JOIN artists AS a + ON m.artist_id = a.id + LEFT OUTER JOIN tags AS t + ON m.name = t.tag + GROUP BY m.id, m.user_id, m.name, u.name, a.id, a.name + ORDER BY m.updated DESC + ) ORDER BY updated DESC LIMIT :offset, :limit ", @@ -938,7 +857,7 @@ class Artists extends Extension $number_of_listings = count($listing); - for ($i = 0 ; $i < $number_of_listings ; $i++) { + for ($i = 0; $i < $number_of_listings; $i++) { $listing[$i]["name"] = stripslashes($listing[$i]["name"]); $listing[$i]["user_name"] = stripslashes($listing[$i]["user_name"]); $listing[$i]["artist_name"] = stripslashes($listing[$i]["artist_name"]); @@ -953,14 +872,14 @@ class Artists extends Extension ON a.id = aa.artist_id "); - $totalPages = (int)ceil($count / $artistsPerPage); + $totalPages = (int) ceil($count / $artistsPerPage); $this->theme->list_artists($listing, $pageNumber + 1, $totalPages); } /* - * HERE WE ADD AN ALIAS - */ + * HERE WE ADD AN ALIAS + */ private function add_urls(): void { global $user; @@ -1081,7 +1000,7 @@ class Artists extends Extension ", ['artist_id' => $artistID]); $rc = count($result); - for ($i = 0 ; $i < $rc ; $i++) { + for ($i = 0; $i < $rc; $i++) { $result[$i]["alias_name"] = stripslashes($result[$i]["alias_name"]); } return $result; diff --git a/ext/auto_tagger/main.php b/ext/auto_tagger/main.php index 08882f70..b71e9809 100644 --- a/ext/auto_tagger/main.php +++ b/ext/auto_tagger/main.php @@ -72,27 +72,23 @@ class AutoTagger extends Extension global $config, $database, $page, $user; if ($event->page_matches("auto_tag")) { - if ($event->get_arg(0) == "add") { - if ($user->can(Permissions::MANAGE_AUTO_TAG)) { - $user->ensure_authed(); - $input = validate_input(["c_tag" => "string", "c_additional_tags" => "string"]); - try { - send_event(new AddAutoTagEvent($input['c_tag'], $input['c_additional_tags'])); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("auto_tag/list")); - } catch (AddAutoTagException $ex) { - $this->theme->display_error(500, "Error adding auto-tag", $ex->getMessage()); - } - } - } elseif ($event->get_arg(0) == "remove") { - if ($user->can(Permissions::MANAGE_AUTO_TAG)) { - $user->ensure_authed(); - $input = validate_input(["d_tag" => "string"]); - send_event(new DeleteAutoTagEvent($input['d_tag'])); + if ($event->page_matches("auto_tag/add", method: "POST", permission: Permissions::MANAGE_AUTO_TAG)) { + $input = validate_input(["c_tag" => "string", "c_additional_tags" => "string"]); + try { + send_event(new AddAutoTagEvent($input['c_tag'], $input['c_additional_tags'])); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("auto_tag/list")); + } catch (AddAutoTagException $ex) { + $this->theme->display_error(500, "Error adding auto-tag", $ex->getMessage()); } - } elseif ($event->get_arg(0) == "list") { + } + if ($event->page_matches("auto_tag/remove", method: "POST", permission: Permissions::MANAGE_AUTO_TAG)) { + $input = validate_input(["d_tag" => "string"]); + send_event(new DeleteAutoTagEvent($input['d_tag'])); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("auto_tag/list")); + } + if ($event->page_matches("auto_tag/list")) { $t = new AutoTaggerTable($database->raw_db()); $t->token = $user->get_auth_token(); $t->inputs = $event->GET; @@ -102,25 +98,23 @@ class AutoTagger extends Extension $t->delete_url = make_link("auto_tag/remove"); } $this->theme->display_auto_tagtable($t->table($t->query()), $t->paginator()); - } elseif ($event->get_arg(0) == "export") { + } + if ($event->page_matches("auto_tag/export")) { $page->set_mode(PageMode::DATA); $page->set_mime(MimeType::CSV); $page->set_filename("auto_tag.csv"); $page->set_data($this->get_auto_tag_csv($database)); - } elseif ($event->get_arg(0) == "import") { - if ($user->can(Permissions::MANAGE_AUTO_TAG)) { - if (count($_FILES) > 0) { - $tmp = $_FILES['auto_tag_file']['tmp_name']; - $contents = file_get_contents_ex($tmp); - $count = $this->add_auto_tag_csv($contents); - log_info(AutoTaggerInfo::KEY, "Imported $count auto-tag definitions from file from file", "Imported $count auto-tag definitions"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("auto_tag/list")); - } else { - $this->theme->display_error(400, "No File Specified", "You have to upload a file"); - } + } + if ($event->page_matches("auto_tag/import", method: "POST", permission: Permissions::MANAGE_AUTO_TAG)) { + if (count($_FILES) > 0) { + $tmp = $_FILES['auto_tag_file']['tmp_name']; + $contents = file_get_contents_ex($tmp); + $count = $this->add_auto_tag_csv($contents); + log_info(AutoTaggerInfo::KEY, "Imported $count auto-tag definitions from file from file", "Imported $count auto-tag definitions"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("auto_tag/list")); } else { - $this->theme->display_error(401, "Admins Only", "Only admins can edit the auto-tag list"); + $this->theme->display_error(400, "No File Specified", "You have to upload a file"); } } } diff --git a/ext/biography/main.php b/ext/biography/main.php index fbe5ada3..cb91b154 100644 --- a/ext/biography/main.php +++ b/ext/biography/main.php @@ -26,13 +26,11 @@ class Biography extends Extension public function onPageRequest(PageRequestEvent $event): void { global $page, $user, $user_config; - if ($event->page_matches("biography")) { - if ($user->check_auth_token()) { - $user_config->set_string("biography", $event->get_POST('biography')); - $page->flash("Bio Updated"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(referer_or(make_link())); - } + if ($event->page_matches("biography", method: "POST")) { + $user_config->set_string("biography", $event->get_POST('biography')); + $page->flash("Bio Updated"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(referer_or(make_link())); } } } diff --git a/ext/blocks/main.php b/ext/blocks/main.php index bd4bf1f1..2edc5f27 100644 --- a/ext/blocks/main.php +++ b/ext/blocks/main.php @@ -68,39 +68,36 @@ class Blocks extends Extension } } - if ($event->page_matches("blocks") && $user->can(Permissions::MANAGE_BLOCKS)) { - if ($event->get_arg(0) == "add") { - if ($user->check_auth_token()) { - $database->execute(" - INSERT INTO blocks (pages, title, area, priority, content, userclass) - VALUES (:pages, :title, :area, :priority, :content, :userclass) - ", ['pages' => $event->req_POST('pages'), 'title' => $event->req_POST('title'), 'area' => $event->req_POST('area'), 'priority' => (int)$event->req_POST('priority'), 'content' => $event->req_POST('content'), 'userclass' => $event->req_POST('userclass')]); - log_info("blocks", "Added Block #".($database->get_last_insert_id('blocks_id_seq'))." (".$event->req_POST('title').")"); - $cache->delete("blocks"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("blocks/list")); - } + if ($event->page_matches("blocks", permission: Permissions::MANAGE_BLOCKS)) { + if ($event->page_matches("blocks/add", method: "POST")) { + $database->execute(" + INSERT INTO blocks (pages, title, area, priority, content, userclass) + VALUES (:pages, :title, :area, :priority, :content, :userclass) + ", ['pages' => $event->req_POST('pages'), 'title' => $event->req_POST('title'), 'area' => $event->req_POST('area'), 'priority' => (int)$event->req_POST('priority'), 'content' => $event->req_POST('content'), 'userclass' => $event->req_POST('userclass')]); + log_info("blocks", "Added Block #".($database->get_last_insert_id('blocks_id_seq'))." (".$event->req_POST('title').")"); + $cache->delete("blocks"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("blocks/list")); } - if ($event->get_arg(0) == "update") { - if ($user->check_auth_token()) { - if (!empty($event->req_POST('delete'))) { - $database->execute(" - DELETE FROM blocks - WHERE id=:id - ", ['id' => $event->req_POST('id')]); - log_info("blocks", "Deleted Block #".$event->req_POST('id')); - } else { - $database->execute(" - UPDATE blocks SET pages=:pages, title=:title, area=:area, priority=:priority, content=:content, userclass=:userclass - WHERE id=:id - ", ['pages' => $event->req_POST('pages'), 'title' => $event->req_POST('title'), 'area' => $event->req_POST('area'), 'priority' => (int)$event->req_POST('priority'), 'content' => $event->req_POST('content'), 'userclass' => $event->req_POST('userclass'), 'id' => $event->req_POST('id')]); - log_info("blocks", "Updated Block #".$event->req_POST('id')." (".$event->req_POST('title').")"); - } - $cache->delete("blocks"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("blocks/list")); + if ($event->page_matches("blocks/update", method: "POST")) { + if (!empty($event->req_POST('delete'))) { + $database->execute(" + DELETE FROM blocks + WHERE id=:id + ", ['id' => $event->req_POST('id')]); + log_info("blocks", "Deleted Block #".$event->req_POST('id')); + } else { + $database->execute(" + UPDATE blocks SET pages=:pages, title=:title, area=:area, priority=:priority, content=:content, userclass=:userclass + WHERE id=:id + ", ['pages' => $event->req_POST('pages'), 'title' => $event->req_POST('title'), 'area' => $event->req_POST('area'), 'priority' => (int)$event->req_POST('priority'), 'content' => $event->req_POST('content'), 'userclass' => $event->req_POST('userclass'), 'id' => $event->req_POST('id')]); + log_info("blocks", "Updated Block #".$event->req_POST('id')." (".$event->req_POST('title').")"); } - } elseif ($event->get_arg(0) == "list") { + $cache->delete("blocks"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("blocks/list")); + } + if ($event->page_matches("blocks/list")) { $this->theme->display_blocks($database->get_all("SELECT * FROM blocks ORDER BY area, priority")); } } diff --git a/ext/blotter/main.php b/ext/blotter/main.php index fc2eb506..18dcb9af 100644 --- a/ext/blotter/main.php +++ b/ext/blotter/main.php @@ -72,60 +72,32 @@ class Blotter extends Extension public function onPageRequest(PageRequestEvent $event): void { global $page, $database, $user; - if ($event->page_matches("blotter") && $event->count_args() > 0) { - switch ($event->get_arg(0)) { - case "editor": - /** - * Displays the blotter editor. - */ - if (!$user->can(Permissions::BLOTTER_ADMIN)) { - $this->theme->display_permission_denied(); - } else { - $entries = $database->get_all("SELECT * FROM blotter ORDER BY id DESC"); - $this->theme->display_editor($entries); - } - break; - case "add": - /** - * Adds an entry - */ - if (!$user->can(Permissions::BLOTTER_ADMIN) || !$user->check_auth_token()) { - $this->theme->display_permission_denied(); - } else { - $entry_text = $event->req_POST('entry_text'); - $important = !is_null($event->get_POST('important')); - // Now insert into db: - $database->execute( - "INSERT INTO blotter (entry_date, entry_text, important) VALUES (now(), :text, :important)", - ["text" => $entry_text, "important" => $important] - ); - log_info("blotter", "Added Message: $entry_text"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("blotter/editor")); - } - break; - case "remove": - /** - * Removes an entry - */ - if (!$user->can(Permissions::BLOTTER_ADMIN) || !$user->check_auth_token()) { - $this->theme->display_permission_denied(); - } else { - $id = int_escape($event->req_POST('id')); - $database->execute("DELETE FROM blotter WHERE id=:id", ["id" => $id]); - log_info("blotter", "Removed Entry #$id"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("blotter/editor")); - } - break; - case "list": - /** - * Displays all blotter entries - */ - $entries = $database->get_all("SELECT * FROM blotter ORDER BY id DESC"); - $this->theme->display_blotter_page($entries); - break; - } + if ($event->page_matches("blotter/editor", method: "GET", permission: Permissions::BLOTTER_ADMIN)) { + $entries = $database->get_all("SELECT * FROM blotter ORDER BY id DESC"); + $this->theme->display_editor($entries); + } + if ($event->page_matches("blotter/add", method: "POST", permission: Permissions::BLOTTER_ADMIN)) { + $entry_text = $event->req_POST('entry_text'); + $important = !is_null($event->get_POST('important')); + // Now insert into db: + $database->execute( + "INSERT INTO blotter (entry_date, entry_text, important) VALUES (now(), :text, :important)", + ["text" => $entry_text, "important" => $important] + ); + log_info("blotter", "Added Message: $entry_text"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("blotter/editor")); + } + if ($event->page_matches("blotter/remove", method: "POST", permission: Permissions::BLOTTER_ADMIN)) { + $id = int_escape($event->req_POST('id')); + $database->execute("DELETE FROM blotter WHERE id=:id", ["id" => $id]); + log_info("blotter", "Removed Entry #$id"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("blotter/editor")); + } + if ($event->page_matches("blotter/list", method: "GET")) { + $entries = $database->get_all("SELECT * FROM blotter ORDER BY id DESC"); + $this->theme->display_blotter_page($entries); } /** * Finally, display the blotter on whatever page we're viewing. @@ -137,7 +109,7 @@ class Blotter extends Extension { global $database, $config; $limit = $config->get_int("blotter_recent", 5); - $sql = 'SELECT * FROM blotter ORDER BY id DESC LIMIT '.intval($limit); + $sql = 'SELECT * FROM blotter ORDER BY id DESC LIMIT ' . intval($limit); $entries = $database->get_all($sql); $this->theme->display_blotter($entries); } diff --git a/ext/blotter/test.php b/ext/blotter/test.php index 26797a2a..c71ac4c5 100644 --- a/ext/blotter/test.php +++ b/ext/blotter/test.php @@ -8,12 +8,15 @@ class BlotterTest extends ShimmiePHPUnitTestCase { public function testDenial(): void { - $this->get_page("blotter/editor"); - $this->assert_response(403); - $this->get_page("blotter/add"); - $this->assert_response(403); - $this->get_page("blotter/remove"); - $this->assert_response(403); + $this->assertException(PermissionDeniedException::class, function () { + $this->get_page("blotter/editor"); + }); + $this->assertException(PermissionDeniedException::class, function () { + $this->post_page("blotter/add"); + }); + $this->assertException(PermissionDeniedException::class, function () { + $this->post_page("blotter/remove"); + }); } public function testAddViewRemove(): void diff --git a/ext/bulk_actions/main.php b/ext/bulk_actions/main.php index e14720f9..e91e7446 100644 --- a/ext/bulk_actions/main.php +++ b/ext/bulk_actions/main.php @@ -169,7 +169,7 @@ class BulkActions extends Extension public function onPageRequest(PageRequestEvent $event): void { global $page, $user; - if ($event->page_matches("bulk_action") && $user->can(Permissions::PERFORM_BULK_ACTIONS)) { + if ($event->page_matches("bulk_action", method: "POST", permission: Permissions::PERFORM_BULK_ACTIONS)) { $action = $event->req_POST('bulk_action'); try { diff --git a/ext/bulk_add/main.php b/ext/bulk_add/main.php index 697f333a..d1007624 100644 --- a/ext/bulk_add/main.php +++ b/ext/bulk_add/main.php @@ -30,13 +30,11 @@ class BulkAdd extends Extension public function onPageRequest(PageRequestEvent $event): void { global $page, $user; - if ($event->page_matches("bulk_add")) { - $dir = $event->get_POST('dir'); - if ($user->can(Permissions::BULK_ADD) && $user->check_auth_token() && $dir) { - shm_set_timeout(null); - $bae = send_event(new BulkAddEvent($dir)); - $this->theme->display_upload_results($page, $bae->results); - } + if ($event->page_matches("bulk_add", method: "POST", permission: Permissions::BULK_ADD)) { + $dir = $event->req_POST('dir'); + shm_set_timeout(null); + $bae = send_event(new BulkAddEvent($dir)); + $this->theme->display_upload_results($page, $bae->results); } } diff --git a/ext/bulk_add_csv/main.php b/ext/bulk_add_csv/main.php index cbdd7f62..1c6dd51a 100644 --- a/ext/bulk_add_csv/main.php +++ b/ext/bulk_add_csv/main.php @@ -16,13 +16,11 @@ class BulkAddCSV extends Extension public function onPageRequest(PageRequestEvent $event): void { global $page, $user; - if ($event->page_matches("bulk_add_csv")) { - $csv = $event->get_POST('csv'); - if ($user->can(Permissions::BULK_ADD) && $user->check_auth_token() && $csv) { - shm_set_timeout(null); - $this->add_csv($csv); - $this->theme->display_upload_results($page); - } + if ($event->page_matches("bulk_add_csv", method: "POST", permission: Permissions::BULK_ADD)) { + $csv = $event->req_POST('csv'); + shm_set_timeout(null); + $this->add_csv($csv); + $this->theme->display_upload_results($page); } } diff --git a/ext/comment/main.php b/ext/comment/main.php index 3d10cd31..7c788d47 100644 --- a/ext/comment/main.php +++ b/ext/comment/main.php @@ -201,74 +201,32 @@ class CommentList extends Extension public function onPageRequest(PageRequestEvent $event): void { - if ($event->page_matches("comment")) { - switch ($event->get_arg(0)) { - case "add": - $this->onPageRequest_add($event); - break; - case "delete": - $this->onPageRequest_delete($event); - break; - case "bulk_delete": - $this->onPageRequest_bulk_delete($event); - break; - case "list": - $this->onPageRequest_list($event); - break; - case "beta-search": - $this->onPageRequest_beta_search($event); - break; - } - } - } - - public function onRobotsBuilding(RobotsBuildingEvent $event): void - { - // comment lists change all the time, crawlers should - // index individual image's comments - $event->add_disallow("comment"); - } - - private function onPageRequest_add(PageRequestEvent $event): void - { - global $user, $page; - try { - $i_iid = int_escape($event->req_POST('image_id')); - send_event(new CommentPostingEvent($i_iid, $user, $event->req_POST('comment'))); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("post/view/$i_iid", null, "comment_on_$i_iid")); - } catch (CommentPostingException $ex) { - $this->theme->display_error(403, "Comment Blocked", $ex->getMessage()); - } - } - - private function onPageRequest_delete(PageRequestEvent $event): void - { - global $user, $page; - if ($user->can(Permissions::DELETE_COMMENT)) { - // FIXME: post, not args - if ($event->count_args() === 3) { - send_event(new CommentDeletionEvent(int_escape($event->get_arg(1)))); - $page->flash("Deleted comment"); + global $cache, $config, $database, $user, $page; + if ($event->page_matches("comment/add", method: "POST", permission: Permissions::CREATE_COMMENT)) { + try { + $i_iid = int_escape($event->req_POST('image_id')); + send_event(new CommentPostingEvent($i_iid, $user, $event->req_POST('comment'))); $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(referer_or(make_link("post/view/" . $event->get_arg(2)))); + $page->set_redirect(make_link("post/view/$i_iid", null, "comment_on_$i_iid")); + } catch (CommentPostingException $ex) { + $this->theme->display_error(403, "Comment Blocked", $ex->getMessage()); } - } else { - $this->theme->display_permission_denied(); } - } - - private function onPageRequest_bulk_delete(PageRequestEvent $event): void - { - global $user, $database, $page; - if ($user->can(Permissions::DELETE_COMMENT)) { + if ($event->page_matches("comment/delete", permission: Permissions::DELETE_COMMENT)) { + // FIXME: post, not args + send_event(new CommentDeletionEvent(int_escape($event->get_arg(0)))); + $page->flash("Deleted comment"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(referer_or(make_link("post/view/" . $event->get_arg(1)))); + } + if ($event->page_matches("comment/bulk_delete", method: "POST", permission: Permissions::DELETE_COMMENT)) { $ip = $event->req_POST('ip'); $comment_ids = $database->get_col(" - SELECT id - FROM comments - WHERE owner_ip=:ip - ", ["ip" => $ip]); + SELECT id + FROM comments + WHERE owner_ip=:ip + ", ["ip" => $ip]); $num = count($comment_ids); log_warning("comment", "Deleting $num comments from $ip"); foreach ($comment_ids as $cid) { @@ -278,74 +236,73 @@ class CommentList extends Extension $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("admin")); - } else { - $this->theme->display_permission_denied(); + } + if ($event->page_matches("comment/list")) { + $threads_per_page = 10; + + $where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : ""; + + $total_pages = cache_get_or_set("comment_pages", fn () => (int)ceil($database->get_one(" + SELECT COUNT(c1) + FROM (SELECT COUNT(image_id) AS c1 FROM comments $where GROUP BY image_id) AS s1 + ") / $threads_per_page), 600); + $total_pages = max($total_pages, 1); + + $current_page = $event->try_page_num(1, $total_pages); + $start = $threads_per_page * $current_page; + + $result = $database->execute(" + SELECT image_id,MAX(posted) AS latest + FROM comments + $where + GROUP BY image_id + ORDER BY latest DESC + LIMIT :limit OFFSET :offset + ", ["limit" => $threads_per_page, "offset" => $start]); + + $user_ratings = Extension::is_enabled(RatingsInfo::KEY) ? Ratings::get_user_class_privs($user) : []; + + $images = []; + while ($row = $result->fetch()) { + $image = Image::by_id((int)$row["image_id"]); + if ( + Extension::is_enabled(RatingsInfo::KEY) && !is_null($image) && + !in_array($image['rating'], $user_ratings) + ) { + $image = null; // this is "clever", I may live to regret it + } + if ( + Extension::is_enabled(ApprovalInfo::KEY) && !is_null($image) && + $config->get_bool(ApprovalConfig::IMAGES) && + $image['approved'] !== true + ) { + $image = null; + } + if (!is_null($image)) { + $comments = $this->get_comments($image->id); + $images[] = [$image, $comments]; + } + } + + $this->theme->display_comment_list($images, $current_page + 1, $total_pages, $user->can(Permissions::CREATE_COMMENT)); + } + if ($event->page_matches("comment/beta-search")) { + $search = $event->get_arg(0); + $page_num = $event->try_page_num(1); + $duser = User::by_name($search); + $i_comment_count = Comment::count_comments_by_user($duser); + $com_per_page = 50; + $total_pages = (int)ceil($i_comment_count / $com_per_page); + $comments = $this->get_user_comments($duser->id, $com_per_page, $page_num * $com_per_page); + $this->theme->display_all_user_comments($comments, $page_num + 1, $total_pages, $duser); } } - private function onPageRequest_list(PageRequestEvent $event): void + public function onRobotsBuilding(RobotsBuildingEvent $event): void { - global $cache, $config, $database, $user; - - $threads_per_page = 10; - - $where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : ""; - - $total_pages = cache_get_or_set("comment_pages", fn () => (int)ceil($database->get_one(" - SELECT COUNT(c1) - FROM (SELECT COUNT(image_id) AS c1 FROM comments $where GROUP BY image_id) AS s1 - ") / $threads_per_page), 600); - $total_pages = max($total_pages, 1); - - $current_page = $event->try_page_num(1, $total_pages); - $start = $threads_per_page * $current_page; - - $result = $database->execute(" - SELECT image_id,MAX(posted) AS latest - FROM comments - $where - GROUP BY image_id - ORDER BY latest DESC - LIMIT :limit OFFSET :offset - ", ["limit" => $threads_per_page, "offset" => $start]); - - $user_ratings = Extension::is_enabled(RatingsInfo::KEY) ? Ratings::get_user_class_privs($user) : []; - - $images = []; - while ($row = $result->fetch()) { - $image = Image::by_id((int)$row["image_id"]); - if ( - Extension::is_enabled(RatingsInfo::KEY) && !is_null($image) && - !in_array($image['rating'], $user_ratings) - ) { - $image = null; // this is "clever", I may live to regret it - } - if ( - Extension::is_enabled(ApprovalInfo::KEY) && !is_null($image) && - $config->get_bool(ApprovalConfig::IMAGES) && - $image['approved'] !== true - ) { - $image = null; - } - if (!is_null($image)) { - $comments = $this->get_comments($image->id); - $images[] = [$image, $comments]; - } - } - - $this->theme->display_comment_list($images, $current_page + 1, $total_pages, $user->can(Permissions::CREATE_COMMENT)); - } - - private function onPageRequest_beta_search(PageRequestEvent $event): void - { - $search = $event->get_arg(1); - $page_num = $event->try_page_num(2); - $duser = User::by_name($search); - $i_comment_count = Comment::count_comments_by_user($duser); - $com_per_page = 50; - $total_pages = (int)ceil($i_comment_count / $com_per_page); - $comments = $this->get_user_comments($duser->id, $com_per_page, $page_num * $com_per_page); - $this->theme->display_all_user_comments($comments, $page_num + 1, $total_pages, $duser); + // comment lists change all the time, crawlers should + // index individual image's comments + $event->add_disallow("comment"); } public function onAdminBuilding(AdminBuildingEvent $event): void diff --git a/ext/et/main.php b/ext/et/main.php index d56bfbb6..6c19af8f 100644 --- a/ext/et/main.php +++ b/ext/et/main.php @@ -16,10 +16,8 @@ class ET extends Extension public function onPageRequest(PageRequestEvent $event): void { global $user; - if ($event->page_matches("system_info")) { - if ($user->can(Permissions::VIEW_SYSINTO)) { - $this->theme->display_info_page($this->to_yaml($this->get_info())); - } + if ($event->page_matches("system_info", permission: Permissions::VIEW_SYSINFO)) { + $this->theme->display_info_page($this->to_yaml($this->get_info())); } } @@ -27,7 +25,7 @@ class ET extends Extension { global $user; if ($event->parent === "system") { - if ($user->can(Permissions::VIEW_SYSINTO)) { + if ($user->can(Permissions::VIEW_SYSINFO)) { $event->add_nav_link("system_info", new Link('system_info'), "System Info", null, 10); } } @@ -36,7 +34,7 @@ class ET extends Extension public function onUserBlockBuilding(UserBlockBuildingEvent $event): void { global $user; - if ($user->can(Permissions::VIEW_SYSINTO)) { + if ($user->can(Permissions::VIEW_SYSINFO)) { $event->add_link("System Info", make_link("system_info"), 99); } } diff --git a/ext/favorites/main.php b/ext/favorites/main.php index 4cc0a4af..1950a832 100644 --- a/ext/favorites/main.php +++ b/ext/favorites/main.php @@ -67,13 +67,13 @@ class Favorites extends Extension return; } // FIXME: proper permissions - if ($event->authed_page_matches("favourite/add")) { + if ($event->page_matches("favourite/add", method: "POST")) { $image_id = int_escape($event->get_arg(0)); send_event(new FavoriteSetEvent($image_id, $user, true)); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/$image_id")); } - if ($event->authed_page_matches("favourite/remove")) { + if ($event->page_matches("favourite/remove", method: "POST")) { $image_id = int_escape($event->get_arg(0)); send_event(new FavoriteSetEvent($image_id, $user, false)); $page->set_mode(PageMode::REDIRECT); diff --git a/ext/featured/main.php b/ext/featured/main.php index 013064ff..192988e9 100644 --- a/ext/featured/main.php +++ b/ext/featured/main.php @@ -19,16 +19,14 @@ class Featured extends Extension { global $config, $page, $user; if ($event->page_matches("featured_image")) { - if ($event->get_arg(0) == "set" && $user->check_auth_token()) { - $id = int_escape($event->get_POST('image_id')); - if ($user->can(Permissions::EDIT_FEATURE) && $id > 0) { - $config->set_int("featured_id", $id); - log_info("featured", "Featured post set to >>$id", "Featured post set"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("post/view/$id")); - } + if ($event->page_matches("featured_image/set", method: "POST", permission: Permissions::EDIT_FEATURE)) { + $id = int_escape($event->req_POST('image_id')); + $config->set_int("featured_id", $id); + log_info("featured", "Featured post set to >>$id", "Featured post set"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("post/view/$id")); } - if ($event->get_arg(0) == "download") { + if ($event->page_matches("featured_image/download")) { $image = Image::by_id($config->get_int("featured_id")); if (!is_null($image)) { $page->set_mode(PageMode::DATA); @@ -36,7 +34,7 @@ class Featured extends Extension $page->set_data(file_get_contents_ex($image->get_image_filename())); } } - if ($event->get_arg(0) == "view") { + if ($event->page_matches("featured_image/view")) { $image = Image::by_id($config->get_int("featured_id")); if (!is_null($image)) { send_event(new DisplayingImageEvent($image)); diff --git a/ext/forum/main.php b/ext/forum/main.php index 568b67c2..74e4af29 100644 --- a/ext/forum/main.php +++ b/ext/forum/main.php @@ -99,99 +99,97 @@ class Forum extends Extension public function onPageRequest(PageRequestEvent $event): void { global $page, $user; - - if ($event->page_matches("forum")) { - switch ($event->get_arg(0)) { - case "index": - $this->show_last_threads($page, $event, $user->can(Permissions::FORUM_ADMIN)); - if (!$user->is_anonymous()) { - $this->theme->display_new_thread_composer($page); - } - break; - case "view": - $threadID = int_escape($event->get_arg(1)); - // $pageNumber = int_escape($event->get_arg(2)); - $errors = $this->sanity_check_viewed_thread($threadID); - - if (count($errors) > 0) { - $this->theme->display_error(500, "Error", implode("
", $errors)); - break; - } - - $this->show_posts($event, $user->can(Permissions::FORUM_ADMIN)); - if ($user->can(Permissions::FORUM_ADMIN)) { - $this->theme->add_actions_block($page, $threadID); - } - if (!$user->is_anonymous()) { - $this->theme->display_new_post_composer($page, $threadID); - } - break; - case "new": - global $page; - $this->theme->display_new_thread_composer($page); - break; - case "create": - $redirectTo = "forum/index"; - if (!$user->is_anonymous()) { - $errors = $this->sanity_check_new_thread(); - - if (count($errors) > 0) { - $this->theme->display_error(500, "Error", implode("
", $errors)); - break; - } - - $newThreadID = $this->save_new_thread($user); - $this->save_new_post($newThreadID, $user); - $redirectTo = "forum/view/".$newThreadID."/1"; - } - - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link($redirectTo)); - - break; - case "delete": - $threadID = int_escape($event->get_arg(1)); - $postID = int_escape($event->get_arg(2)); - - if ($user->can(Permissions::FORUM_ADMIN)) { - $this->delete_post($postID); - } - - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("forum/view/".$threadID)); - break; - case "nuke": - $threadID = int_escape($event->get_arg(1)); - - if ($user->can(Permissions::FORUM_ADMIN)) { - $this->delete_thread($threadID); - } - - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("forum/index")); - break; - case "answer": - $threadID = int_escape($event->req_POST("threadID")); - $total_pages = $this->get_total_pages_for_thread($threadID); - if (!$user->is_anonymous()) { - $errors = $this->sanity_check_new_post(); - - if (count($errors) > 0) { - $this->theme->display_error(500, "Error", implode("
", $errors)); - break; - } - $this->save_new_post($threadID, $user); - } - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("forum/view/".$threadID."/".$total_pages)); - break; - default: - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("forum/index")); - //$this->theme->display_error(400, "Invalid action", "You should check forum/index."); - break; + if ($event->page_matches("forum/index")) { + if ($event->count_args() >= 2) { + $pageNumber = page_number($event->get_arg(1)); + } else { + $pageNumber = 0; + } + $this->show_last_threads($page, $pageNumber, $user->can(Permissions::FORUM_ADMIN)); + if (!$user->is_anonymous()) { + $this->theme->display_new_thread_composer($page); } } + if ($event->page_matches("forum/view")) { + $threadID = int_escape($event->get_arg(1)); + // $pageNumber = int_escape($event->get_arg(2)); + $errors = $this->sanity_check_viewed_thread($threadID); + + if (count($errors) > 0) { + throw new UserErrorException(implode("
", $errors)); + } + + $threadID = int_escape($event->get_arg(1)); + if ($event->count_args() >= 3) { + $pageNumber = page_number($event->get_arg(2)); + } else { + $pageNumber = 0; + } + + $this->show_posts($threadID, $pageNumber, $user->can(Permissions::FORUM_ADMIN)); + if ($user->can(Permissions::FORUM_ADMIN)) { + $this->theme->add_actions_block($page, $threadID); + } + if (!$user->is_anonymous()) { + $this->theme->display_new_post_composer($page, $threadID); + } + } + if ($event->page_matches("forum/new")) { + $this->theme->display_new_thread_composer($page); + } + if ($event->page_matches("forum/create")) { + $redirectTo = "forum/index"; + if (!$user->is_anonymous()) { + $errors = $this->sanity_check_new_thread(); + + if (count($errors) > 0) { + throw new UserErrorException(implode("
", $errors)); + } + + $newThreadID = $this->save_new_thread($user); + $this->save_new_post($newThreadID, $user); + $redirectTo = "forum/view/" . $newThreadID . "/1"; + } + + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link($redirectTo)); + } + if ($event->page_matches("forum/delete")) { + $threadID = int_escape($event->get_arg(1)); + $postID = int_escape($event->get_arg(2)); + + if ($user->can(Permissions::FORUM_ADMIN)) { + $this->delete_post($postID); + } + + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("forum/view/" . $threadID)); + } + if ($event->page_matches("forum/nuke")) { + $threadID = int_escape($event->get_arg(1)); + + if ($user->can(Permissions::FORUM_ADMIN)) { + $this->delete_thread($threadID); + } + + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("forum/index")); + } + if ($event->page_matches("forum/answer")) { + $threadID = int_escape($event->req_POST("threadID")); + $total_pages = $this->get_total_pages_for_thread($threadID); + if (!$user->is_anonymous()) { + $errors = $this->sanity_check_new_post(); + + if (count($errors) > 0) { + throw new UserErrorException(implode("
", $errors)); + } + $this->save_new_post($threadID, $user); + } + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("forum/view/" . $threadID . "/" . $total_pages)); + } + } private function get_total_pages_for_thread(int $threadID): int @@ -203,7 +201,7 @@ class Forum extends Extension WHERE thread_id = :thread_id ", ['thread_id' => $threadID]); - return (int)ceil($result["count"] / $config->get_int("forumPostsPerPage")); + return (int) ceil($result["count"] / $config->get_int("forumPostsPerPage")); } /** @@ -268,55 +266,42 @@ class Forum extends Extension return $database->get_one("SELECT t.title FROM forum_threads AS t WHERE t.id = :id ", ['id' => $threadID]); } - private function show_last_threads(Page $page, PageRequestEvent $event, bool $showAdminOptions = false): void + private function show_last_threads(Page $page, int $pageNumber, bool $showAdminOptions = false): void { global $config, $database; $threadsPerPage = $config->get_int('forumThreadsPerPage', 15); - $totalPages = (int)ceil($database->get_one("SELECT COUNT(*) FROM forum_threads") / $threadsPerPage); - - if ($event->count_args() >= 2) { - $pageNumber = page_number($event->get_arg(1), $totalPages); - } else { - $pageNumber = 0; - } + $totalPages = (int) ceil($database->get_one("SELECT COUNT(*) FROM forum_threads") / $threadsPerPage); $threads = $database->get_all( - "SELECT f.id, f.sticky, f.title, f.date, f.uptodate, u.name AS user_name, u.email AS user_email, u.class AS user_class, sum(1) - 1 AS response_count ". - "FROM forum_threads AS f ". - "INNER JOIN users AS u ". - "ON f.user_id = u.id ". - "INNER JOIN forum_posts AS p ". - "ON p.thread_id = f.id ". - "GROUP BY f.id, f.sticky, f.title, f.date, u.name, u.email, u.class ". - "ORDER BY f.sticky ASC, f.uptodate DESC LIMIT :limit OFFSET :offset", + "SELECT f.id, f.sticky, f.title, f.date, f.uptodate, u.name AS user_name, u.email AS user_email, u.class AS user_class, sum(1) - 1 AS response_count " . + "FROM forum_threads AS f " . + "INNER JOIN users AS u " . + "ON f.user_id = u.id " . + "INNER JOIN forum_posts AS p " . + "ON p.thread_id = f.id " . + "GROUP BY f.id, f.sticky, f.title, f.date, u.name, u.email, u.class " . + "ORDER BY f.sticky ASC, f.uptodate DESC LIMIT :limit OFFSET :offset", ["limit" => $threadsPerPage, "offset" => $pageNumber * $threadsPerPage] ); $this->theme->display_thread_list($page, $threads, $showAdminOptions, $pageNumber + 1, $totalPages); } - private function show_posts(PageRequestEvent $event, bool $showAdminOptions = false): void + private function show_posts(int $threadID, int $pageNumber, bool $showAdminOptions = false): void { global $config, $database; - $threadID = int_escape($event->get_arg(1)); $postsPerPage = $config->get_int('forumPostsPerPage', 15); - $totalPages = (int)ceil($database->get_one("SELECT COUNT(*) FROM forum_posts WHERE thread_id = :id", ['id' => $threadID]) / $postsPerPage); + $totalPages = (int) ceil($database->get_one("SELECT COUNT(*) FROM forum_posts WHERE thread_id = :id", ['id' => $threadID]) / $postsPerPage); $threadTitle = $this->get_thread_title($threadID); - if ($event->count_args() >= 3) { - $pageNumber = page_number($event->get_arg(2), $totalPages); - } else { - $pageNumber = 0; - } - $posts = $database->get_all( - "SELECT p.id, p.date, p.message, u.name as user_name, u.email AS user_email, u.class AS user_class ". - "FROM forum_posts AS p ". - "INNER JOIN users AS u ". - "ON p.user_id = u.id ". - "WHERE thread_id = :thread_id ". - "ORDER BY p.date ASC ". - "LIMIT :limit OFFSET :offset", + "SELECT p.id, p.date, p.message, u.name as user_name, u.email AS user_email, u.class AS user_class " . + "FROM forum_posts AS p " . + "INNER JOIN users AS u " . + "ON p.user_id = u.id " . + "WHERE thread_id = :thread_id " . + "ORDER BY p.date ASC " . + "LIMIT :limit OFFSET :offset", ["thread_id" => $threadID, "offset" => $pageNumber * $postsPerPage, "limit" => $postsPerPage] ); $this->theme->display_thread($posts, $showAdminOptions, $threadTitle, $threadID, $pageNumber + 1, $totalPages); diff --git a/ext/image/main.php b/ext/image/main.php index ca2e31c4..c7b57709 100644 --- a/ext/image/main.php +++ b/ext/image/main.php @@ -88,19 +88,17 @@ class ImageIO extends Extension $thumb_height = $config->get_int(ImageConfig::THUMB_HEIGHT, 192); $page->add_html_header(""); - if ($event->page_matches("image/delete")) { + if ($event->page_matches("image/delete", method: "POST", permission: Permissions::DELETE_IMAGE)) { global $page, $user; - if ($user->can(Permissions::DELETE_IMAGE) && $event->get_POST('image_id') && $user->check_auth_token()) { - $image = Image::by_id(int_escape($event->get_POST('image_id'))); - if ($image) { - send_event(new ImageDeletionEvent($image)); + $image = Image::by_id(int_escape($event->req_POST('image_id'))); + if ($image) { + send_event(new ImageDeletionEvent($image)); - if ($config->get_string(ImageConfig::ON_DELETE) === ImageConfig::ON_DELETE_NEXT) { - redirect_to_next_image($image, $event->get_GET('search')); - } else { - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(referer_or(make_link(), ['post/view'])); - } + if ($config->get_string(ImageConfig::ON_DELETE) === ImageConfig::ON_DELETE_NEXT) { + redirect_to_next_image($image, $event->get_GET('search')); + } else { + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(referer_or(make_link(), ['post/view'])); } } } elseif ($event->page_matches("image")) { diff --git a/ext/image_hash_ban/main.php b/ext/image_hash_ban/main.php index 34cd8639..8bc18239 100644 --- a/ext/image_hash_ban/main.php +++ b/ext/image_hash_ban/main.php @@ -89,41 +89,39 @@ class ImageBan extends Extension { global $database, $page, $user; - if ($event->page_matches("image_hash_ban")) { - if ($user->can(Permissions::BAN_IMAGE)) { - if ($event->get_arg(0) == "add") { - $user->ensure_authed(); - $input = validate_input(["c_hash" => "optional,string", "c_reason" => "string", "c_image_id" => "optional,int"]); - $image = isset($input['c_image_id']) ? Image::by_id($input['c_image_id']) : null; - $hash = isset($input["c_hash"]) ? $input["c_hash"] : $image->hash; - $reason = isset($input['c_reason']) ? $input['c_reason'] : "DNP"; + if ($event->page_matches("image_hash_ban", permission: Permissions::BAN_IMAGE)) { + if ($event->page_matches("image_hash_ban/add", method: "POST")) { + $input = validate_input(["c_hash" => "optional,string", "c_reason" => "string", "c_image_id" => "optional,int"]); + $image = isset($input['c_image_id']) ? Image::by_id($input['c_image_id']) : null; + $hash = isset($input["c_hash"]) ? $input["c_hash"] : $image->hash; + $reason = isset($input['c_reason']) ? $input['c_reason'] : "DNP"; - if ($hash) { - send_event(new AddImageHashBanEvent($hash, $reason)); - $page->flash("Post ban added"); + if ($hash) { + send_event(new AddImageHashBanEvent($hash, $reason)); + $page->flash("Post ban added"); - if ($image) { - send_event(new ImageDeletionEvent($image)); - $page->flash("Post deleted"); - } - - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(referer_or(make_link())); + if ($image) { + send_event(new ImageDeletionEvent($image)); + $page->flash("Post deleted"); } - } elseif ($event->get_arg(0) == "remove") { - $user->ensure_authed(); - $input = validate_input(["d_hash" => "string"]); - send_event(new RemoveImageHashBanEvent($input['d_hash'])); - $page->flash("Post ban removed"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(referer_or(make_link())); - } elseif ($event->get_arg(0) == "list") { - $t = new HashBanTable($database->raw_db()); - $t->token = $user->get_auth_token(); - $t->inputs = $event->GET; - $this->theme->display_crud("Post Bans", $t->table($t->query()), $t->paginator()); } } + if ($event->page_matches("image_hash_ban/remove", method: "POST")) { + $input = validate_input(["d_hash" => "string"]); + send_event(new RemoveImageHashBanEvent($input['d_hash'])); + $page->flash("Post ban removed"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(referer_or(make_link())); + } + if ($event->page_matches("image_hash_ban/list")) { + $t = new HashBanTable($database->raw_db()); + $t->token = $user->get_auth_token(); + $t->inputs = $event->GET; + $this->theme->display_crud("Post Bans", $t->table($t->query()), $t->paginator()); + } } } diff --git a/ext/ipban/main.php b/ext/ipban/main.php index 5ba55976..17758292 100644 --- a/ext/ipban/main.php +++ b/ext/ipban/main.php @@ -180,33 +180,31 @@ class IPBan extends Extension public function onPageRequest(PageRequestEvent $event): void { - if ($event->page_matches("ip_ban")) { + if ($event->page_matches("ip_ban", permission: Permissions::BAN_IP)) { 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'])); - $page->flash("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'])); - $page->flash("Ban removed"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("ip_ban/list")); - } elseif ($event->get_arg(0) == "list") { - $event->GET['c_banner'] = $user->name; - $event->GET['c_added'] = date('Y-m-d'); - $t = new IPBanTable($database->raw_db()); - $t->token = $user->get_auth_token(); - $t->inputs = $event->GET; - $this->theme->display_bans($page, $t->table($t->query()), $t->paginator()); - } - } else { - $this->theme->display_permission_denied(); + if ($event->page_matches("ip_ban/create", method: "POST")) { + $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'])); + $page->flash("Ban for {$input['c_ip']} added"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("ip_ban/list")); + } + if ($event->page_matches("ip_ban/delete", method: "POST")) { + $user->ensure_authed(); + $input = validate_input(["d_id" => "int"]); + send_event(new RemoveIPBanEvent($input['d_id'])); + $page->flash("Ban removed"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("ip_ban/list")); + } + if ($event->page_matches("ip_ban/list")) { + $event->GET['c_banner'] = $user->name; + $event->GET['c_added'] = date('Y-m-d'); + $t = new IPBanTable($database->raw_db()); + $t->token = $user->get_auth_token(); + $t->inputs = $event->GET; + $this->theme->display_bans($page, $t->table($t->query()), $t->paginator()); } } } diff --git a/ext/ipban/test.php b/ext/ipban/test.php index 4be3e31d..d6c640c4 100644 --- a/ext/ipban/test.php +++ b/ext/ipban/test.php @@ -10,9 +10,9 @@ class IPBanTest extends ShimmiePHPUnitTestCase public function testAccess(): void { - $page = $this->get_page('ip_ban/list'); - $this->assertEquals(403, $page->code); - $this->assertEquals("Permission Denied", $page->title); + $this->assertException(PermissionDeniedException::class, function () { + $this->get_page('ip_ban/list'); + }); } public function testIPBan(): void diff --git a/ext/log_db/main.php b/ext/log_db/main.php index 2da2d34f..1d1a1efd 100644 --- a/ext/log_db/main.php +++ b/ext/log_db/main.php @@ -278,12 +278,10 @@ class LogDatabase extends Extension public function onPageRequest(PageRequestEvent $event): void { global $database, $user; - if ($event->page_matches("log/view")) { - if ($user->can(Permissions::VIEW_EVENTLOG)) { - $t = new LogTable($database->raw_db()); - $t->inputs = $event->GET; - $this->theme->display_crud("Event Log", $t->table($t->query()), $t->paginator()); - } + if ($event->page_matches("log/view", permission: Permissions::VIEW_EVENTLOG)) { + $t = new LogTable($database->raw_db()); + $t->inputs = $event->GET; + $this->theme->display_crud("Event Log", $t->table($t->query()), $t->paginator()); } } diff --git a/ext/media/main.php b/ext/media/main.php index 8a085fae..bc9d4c6a 100644 --- a/ext/media/main.php +++ b/ext/media/main.php @@ -75,7 +75,7 @@ class Media extends Extension global $page, $user; if ( - $event->authed_page_matches("media_rescan") && + $event->page_matches("media_rescan", method: "POST") && $user->can(Permissions::RESCAN_MEDIA) ) { $image = Image::by_id(int_escape($event->get_arg(0))); diff --git a/ext/not_a_tag/main.php b/ext/not_a_tag/main.php index 294a9c19..72a4200d 100644 --- a/ext/not_a_tag/main.php +++ b/ext/not_a_tag/main.php @@ -126,33 +126,31 @@ class NotATag extends Extension { global $database, $page, $user; - if ($event->page_matches("untag")) { - if ($user->can(Permissions::BAN_IMAGE)) { - if ($event->get_arg(0) == "add") { - $user->ensure_authed(); - $input = validate_input(["c_tag" => "string", "c_redirect" => "string"]); - $database->execute( - "INSERT INTO untags(tag, redirect) VALUES (:tag, :redirect)", - ["tag" => $input['c_tag'], "redirect" => $input['c_redirect']] - ); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(referer_or(make_link())); - } elseif ($event->get_arg(0) == "remove") { - $user->ensure_authed(); - $input = validate_input(["d_tag" => "string"]); - $database->execute( - "DELETE FROM untags WHERE LOWER(tag) = LOWER(:tag)", - ["tag" => $input['d_tag']] - ); - $page->flash("Post ban removed"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(referer_or(make_link())); - } elseif ($event->get_arg(0) == "list") { - $t = new NotATagTable($database->raw_db()); - $t->token = $user->get_auth_token(); - $t->inputs = $event->GET; - $this->theme->display_crud("UnTags", $t->table($t->query()), $t->paginator()); - } + if ($event->page_matches("untag", permission: Permissions::BAN_IMAGE)) { + if ($event->page_matches("untag/add", method: "POST")) { + $input = validate_input(["c_tag" => "string", "c_redirect" => "string"]); + $database->execute( + "INSERT INTO untags(tag, redirect) VALUES (:tag, :redirect)", + ["tag" => $input['c_tag'], "redirect" => $input['c_redirect']] + ); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(referer_or(make_link())); + } + if ($event->page_matches("untag/remove", method: "POST")) { + $input = validate_input(["d_tag" => "string"]); + $database->execute( + "DELETE FROM untags WHERE LOWER(tag) = LOWER(:tag)", + ["tag" => $input['d_tag']] + ); + $page->flash("Post ban removed"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(referer_or(make_link())); + } + if ($event->page_matches("untag/list")) { + $t = new NotATagTable($database->raw_db()); + $t->token = $user->get_auth_token(); + $t->inputs = $event->GET; + $this->theme->display_crud("UnTags", $t->table($t->query()), $t->paginator()); } } } diff --git a/ext/notes/main.php b/ext/notes/main.php index bee206bd..4372eeca 100644 --- a/ext/notes/main.php +++ b/ext/notes/main.php @@ -78,92 +78,81 @@ class Notes extends Extension public function onPageRequest(PageRequestEvent $event): void { global $page, $user; - if ($event->page_matches("note")) { - switch ($event->get_arg(0)) { - case "list": //index - $this->get_notes_list($event); // This should show images like post/list but i don't know how do that. - break; - case "requests": // The same as post/list but only for note_request table. - $this->get_notes_requests($event); // This should show images like post/list but i don't know how do that. - break; - case "search": - if (!$user->is_anonymous()) { - $this->theme->search_notes_page($page); - } - break; - case "updated": //Thinking how to build this function. - $this->get_histories($event); - break; - case "history": //Thinking how to build this function. - $this->get_history($event); - break; - case "revert": - $noteID = int_escape($event->get_arg(1)); - $reviewID = int_escape($event->get_arg(2)); - if (!$user->is_anonymous()) { - $this->revert_history($noteID, $reviewID); - } - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("note/updated")); - break; - - case "add_request": - $image_id = int_escape($event->req_POST("image_id")); - if (!$user->is_anonymous()) { - $this->add_note_request($image_id); - } - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("post/view/$image_id")); - break; - case "nuke_requests": - $image_id = int_escape($event->req_POST("image_id")); - if ($user->can(Permissions::NOTES_ADMIN)) { - $this->nuke_requests($image_id); - } - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("post/view/$image_id")); - break; - - case "create_note": - $page->set_mode(PageMode::DATA); - if (!$user->is_anonymous()) { - $note_id = $this->add_new_note(); - $page->set_data(json_encode_ex([ - 'status' => 'success', - 'note_id' => $note_id, - ])); - } - break; - case "update_note": - $page->set_mode(PageMode::DATA); - if (!$user->is_anonymous()) { - $this->update_note(); - $page->set_data(json_encode_ex(['status' => 'success'])); - } - break; - case "delete_note": - $page->set_mode(PageMode::DATA); - if ($user->can(Permissions::NOTES_ADMIN)) { - $this->delete_note(); - $page->set_data(json_encode_ex(['status' => 'success'])); - } - break; - case "nuke_notes": - $image_id = int_escape($event->req_POST("image_id")); - if ($user->can(Permissions::NOTES_ADMIN)) { - $this->nuke_notes($image_id); - } - - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("post/view/$image_id")); - break; - - default: - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("note/list")); - break; + if ($event->page_matches("note/lost")) { + $this->get_notes_list($event->try_page_num(0)); // This should show images like post/list but i don't know how do that. + } + if ($event->page_matches("note/requests")) { + $this->get_notes_requests($event->try_page_num(0)); // This should show images like post/list but i don't know how do that. + } + if ($event->page_matches("note/search")) { + if (!$user->is_anonymous()) { + $this->theme->search_notes_page($page); } } + if ($event->page_matches("note/updated")) { + $this->get_histories($event->try_page_num(0)); + } + if ($event->page_matches("note/history")) { + $this->get_history(int_escape($event->get_arg(0)), $event->try_page_num(1)); + } + if ($event->page_matches("note/revert")) { + $noteID = int_escape($event->get_arg(0)); + $reviewID = int_escape($event->get_arg(1)); + if (!$user->is_anonymous()) { + $this->revert_history($noteID, $reviewID); + } + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("note/updated")); + } + if ($event->page_matches("note/add_request")) { + $image_id = int_escape($event->req_POST("image_id")); + if (!$user->is_anonymous()) { + $this->add_note_request($image_id); + } + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("post/view/$image_id")); + } + if ($event->page_matches("note/nuke_requests")) { + $image_id = int_escape($event->req_POST("image_id")); + if ($user->can(Permissions::NOTES_ADMIN)) { + $this->nuke_requests($image_id); + } + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("post/view/$image_id")); + } + if ($event->page_matches("note/create_note")) { + $page->set_mode(PageMode::DATA); + if (!$user->is_anonymous()) { + $note_id = $this->add_new_note(); + $page->set_data(json_encode_ex([ + 'status' => 'success', + 'note_id' => $note_id, + ])); + } + } + if ($event->page_matches("note/update_note")) { + $page->set_mode(PageMode::DATA); + if (!$user->is_anonymous()) { + $this->update_note(); + $page->set_data(json_encode_ex(['status' => 'success'])); + } + } + if ($event->page_matches("note/delete_note")) { + $page->set_mode(PageMode::DATA); + if ($user->can(Permissions::NOTES_ADMIN)) { + $this->delete_note(); + $page->set_data(json_encode_ex(['status' => 'success'])); + } + } + if ($event->page_matches("note/nuke_notes")) { + $image_id = int_escape($event->req_POST("image_id")); + if ($user->can(Permissions::NOTES_ADMIN)) { + $this->nuke_notes($image_id); + } + + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("post/view/$image_id")); + } } @@ -364,13 +353,12 @@ class Notes extends Extension log_info("notes", "Requests deleted from {$image_id} by {$user->name}"); } - private function get_notes_list(PageRequestEvent $event): void + private function get_notes_list(int $pageNumber): void { global $database, $config; - $pageNumber = $event->try_page_num(1); $notesPerPage = $config->get_int('notesNotesPerPage'); - $totalPages = (int)ceil($database->get_one("SELECT COUNT(DISTINCT image_id) FROM notes") / $notesPerPage); + $totalPages = (int) ceil($database->get_one("SELECT COUNT(DISTINCT image_id) FROM notes") / $notesPerPage); //$result = $database->get_all("SELECT * FROM pool_images WHERE pool_id=:pool_id", ['pool_id'=>$poolID]); $image_ids = $database->get_col( @@ -383,19 +371,17 @@ class Notes extends Extension ); $images = []; - foreach($image_ids as $id) { + foreach ($image_ids as $id) { $images[] = Image::by_id($id); } $this->theme->display_note_list($images, $pageNumber + 1, $totalPages); } - private function get_notes_requests(PageRequestEvent $event): void + private function get_notes_requests(int $pageNumber): void { global $config, $database; - $pageNumber = $event->try_page_num(1); - $requestsPerPage = $config->get_int('notesRequestsPerPage'); //$result = $database->get_all("SELECT * FROM pool_images WHERE pool_id=:pool_id", ['pool_id'=>$poolID]); @@ -408,7 +394,7 @@ class Notes extends Extension ["offset" => $pageNumber * $requestsPerPage, "limit" => $requestsPerPage] ); - $totalPages = (int)ceil($database->get_one("SELECT COUNT(*) FROM note_request") / $requestsPerPage); + $totalPages = (int) ceil($database->get_one("SELECT COUNT(*) FROM note_request") / $requestsPerPage); $images = []; while ($row = $result->fetch()) { @@ -430,54 +416,60 @@ class Notes extends Extension INSERT INTO note_histories (note_enable, note_id, review_id, image_id, user_id, user_ip, date, x1, y1, height, width, note) VALUES (:note_enable, :note_id, :review_id, :image_id, :user_id, :user_ip, now(), :x1, :y1, :height, :width, :note) ", - ['note_enable' => $noteEnable, 'note_id' => $noteID, 'review_id' => $reviewID, 'image_id' => $imageID, 'user_id' => $user->id, 'user_ip' => get_real_ip(), - 'x1' => $noteX1, 'y1' => $noteY1, 'height' => $noteHeight, 'width' => $noteWidth, 'note' => $noteText] + [ + 'note_enable' => $noteEnable, + 'note_id' => $noteID, + 'review_id' => $reviewID, + 'image_id' => $imageID, + 'user_id' => $user->id, + 'user_ip' => get_real_ip(), + 'x1' => $noteX1, + 'y1' => $noteY1, + 'height' => $noteHeight, + 'width' => $noteWidth, + 'note' => $noteText + ] ); } - private function get_histories(PageRequestEvent $event): void + private function get_histories(int $pageNumber): void { global $config, $database; - $pageNumber = $event->try_page_num(1); - $historiesPerPage = $config->get_int('notesHistoriesPerPage'); //ORDER BY IMAGE & DATE $histories = $database->get_all( - "SELECT h.note_id, h.review_id, h.image_id, h.date, h.note, u.name AS user_name ". - "FROM note_histories AS h ". - "INNER JOIN users AS u ". - "ON u.id = h.user_id ". - "ORDER BY date DESC LIMIT :limit OFFSET :offset", + "SELECT h.note_id, h.review_id, h.image_id, h.date, h.note, u.name AS user_name " . + "FROM note_histories AS h " . + "INNER JOIN users AS u " . + "ON u.id = h.user_id " . + "ORDER BY date DESC LIMIT :limit OFFSET :offset", ['offset' => $pageNumber * $historiesPerPage, 'limit' => $historiesPerPage] ); - $totalPages = (int)ceil($database->get_one("SELECT COUNT(*) FROM note_histories") / $historiesPerPage); + $totalPages = (int) ceil($database->get_one("SELECT COUNT(*) FROM note_histories") / $historiesPerPage); $this->theme->display_histories($histories, $pageNumber + 1, $totalPages); } - private function get_history(PageRequestEvent $event): void + private function get_history(int $noteID, int $pageNumber): void { global $config, $database; - $noteID = $event->get_arg(1); - $pageNumber = $event->try_page_num(2); - $historiesPerPage = $config->get_int('notesHistoriesPerPage'); $histories = $database->get_all( - "SELECT h.note_id, h.review_id, h.image_id, h.date, h.note, u.name AS user_name ". - "FROM note_histories AS h ". - "INNER JOIN users AS u ". - "ON u.id = h.user_id ". - "WHERE note_id = :note_id ". - "ORDER BY date DESC LIMIT :limit OFFSET :offset", + "SELECT h.note_id, h.review_id, h.image_id, h.date, h.note, u.name AS user_name " . + "FROM note_histories AS h " . + "INNER JOIN users AS u " . + "ON u.id = h.user_id " . + "WHERE note_id = :note_id " . + "ORDER BY date DESC LIMIT :limit OFFSET :offset", ['note_id' => $noteID, 'offset' => $pageNumber * $historiesPerPage, 'limit' => $historiesPerPage] ); - $totalPages = (int)ceil($database->get_one("SELECT COUNT(*) FROM note_histories WHERE note_id = :note_id", ['note_id' => $noteID]) / $historiesPerPage); + $totalPages = (int) ceil($database->get_one("SELECT COUNT(*) FROM note_histories WHERE note_id = :note_id", ['note_id' => $noteID]) / $historiesPerPage); $this->theme->display_history($histories, $pageNumber + 1, $totalPages); } @@ -492,13 +484,13 @@ class Notes extends Extension $history = $database->get_row("SELECT * FROM note_histories WHERE note_id = :note_id AND review_id = :review_id", ['note_id' => $noteID, 'review_id' => $reviewID]); $noteEnable = $history['note_enable']; - $noteID = $history['note_id']; - $imageID = $history['image_id']; - $noteX1 = $history['x1']; - $noteY1 = $history['y1']; + $noteID = $history['note_id']; + $imageID = $history['image_id']; + $noteX1 = $history['x1']; + $noteY1 = $history['y1']; $noteHeight = $history['height']; - $noteWidth = $history['width']; - $noteText = $history['note']; + $noteWidth = $history['width']; + $noteText = $history['note']; $database->execute(" UPDATE notes diff --git a/ext/numeric_score/main.php b/ext/numeric_score/main.php index a257fb95..43b517bc 100644 --- a/ext/numeric_score/main.php +++ b/ext/numeric_score/main.php @@ -156,36 +156,30 @@ class NumericScore extends Extension $html .= ""; } die($html); - } elseif ($event->page_matches("numeric_score_vote") && $user->check_auth_token()) { - if ($user->can(Permissions::CREATE_VOTE)) { - $image_id = int_escape($event->req_POST("image_id")); - $score = int_escape($event->req_POST("vote")); - if (($score == -1 || $score == 0 || $score == 1) && $image_id > 0) { - send_event(new NumericScoreSetEvent($image_id, $user, $score)); - } - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("post/view/$image_id")); - } - } elseif ($event->page_matches("numeric_score/remove_votes_on") && $user->check_auth_token()) { - if ($user->can(Permissions::EDIT_OTHER_VOTE)) { - $image_id = int_escape($event->req_POST("image_id")); - $database->execute( - "DELETE FROM numeric_score_votes WHERE image_id=:image_id", - ['image_id' => $image_id] - ); - $database->execute( - "UPDATE images SET numeric_score=0 WHERE id=:id", - ['id' => $image_id] - ); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("post/view/$image_id")); - } - } elseif ($event->page_matches("numeric_score/remove_votes_by") && $user->check_auth_token()) { - if ($user->can(Permissions::EDIT_OTHER_VOTE)) { - $this->delete_votes_by(int_escape($event->req_POST('user_id'))); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link()); + } elseif ($event->page_matches("numeric_score_vote", method: "POST", permission: Permissions::CREATE_VOTE)) { + $image_id = int_escape($event->req_POST("image_id")); + $score = int_escape($event->req_POST("vote")); + if (($score == -1 || $score == 0 || $score == 1) && $image_id > 0) { + send_event(new NumericScoreSetEvent($image_id, $user, $score)); } + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("post/view/$image_id")); + } elseif ($event->page_matches("numeric_score/remove_votes_on", method: "POST", permission: Permissions::EDIT_OTHER_VOTE)) { + $image_id = int_escape($event->req_POST("image_id")); + $database->execute( + "DELETE FROM numeric_score_votes WHERE image_id=:image_id", + ['image_id' => $image_id] + ); + $database->execute( + "UPDATE images SET numeric_score=0 WHERE id=:id", + ['id' => $image_id] + ); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("post/view/$image_id")); + } elseif ($event->page_matches("numeric_score/remove_votes_by", method: "POST", permission: Permissions::EDIT_OTHER_VOTE)) { + $this->delete_votes_by(int_escape($event->req_POST('user_id'))); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link()); } elseif ($event->page_matches("popular_by_day") || $event->page_matches("popular_by_month") || $event->page_matches("popular_by_year")) { //FIXME: popular_by isn't linked from anywhere list($day, $month, $year) = [date("d"), date("m"), date("Y")]; diff --git a/ext/pm/main.php b/ext/pm/main.php index b77654d5..07bfebde 100644 --- a/ext/pm/main.php +++ b/ext/pm/main.php @@ -227,66 +227,49 @@ class PrivMsg extends Extension public function onPageRequest(PageRequestEvent $event): void { global $cache, $database, $page, $user; - if ($event->page_matches("pm")) { - switch ($event->get_arg(0)) { - case "read": - if ($user->can(Permissions::READ_PM)) { - $pm_id = int_escape($event->get_arg(1)); - $pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", ["id" => $pm_id]); - if (is_null($pm)) { - $this->theme->display_error(404, "No such PM", "There is no PM #$pm_id"); - } elseif (($pm["to_id"] == $user->id) || $user->can(Permissions::VIEW_OTHER_PMS)) { - $from_user = User::by_id((int)$pm["from_id"]); - if ($pm["to_id"] == $user->id) { - $database->execute("UPDATE private_message SET is_read=true WHERE id = :id", ["id" => $pm_id]); - $cache->delete("pm-count-{$user->id}"); - } - $pmo = PM::from_row($pm); - $this->theme->display_message($page, $from_user, $user, $pmo); - if($user->can(Permissions::SEND_PM)) { - $this->theme->display_composer($page, $user, $from_user, "Re: ".$pmo->subject); - } - } else { - $this->theme->display_permission_denied(); - } - } - break; - case "delete": - if ($user->can(Permissions::READ_PM)) { - if ($user->check_auth_token()) { - $pm_id = int_escape($event->get_POST("pm_id")); - $pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", ["id" => $pm_id]); - if (is_null($pm)) { - $this->theme->display_error(404, "No such PM", "There is no PM #$pm_id"); - } elseif (($pm["to_id"] == $user->id) || $user->can(Permissions::VIEW_OTHER_PMS)) { - $database->execute("DELETE FROM private_message WHERE id = :id", ["id" => $pm_id]); - $cache->delete("pm-count-{$user->id}"); - log_info("pm", "Deleted PM #$pm_id", "PM deleted"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(referer_or(make_link())); - } - } - } - break; - case "send": - if ($user->can(Permissions::SEND_PM)) { - if ($user->check_auth_token()) { - $to_id = int_escape($event->get_POST("to_id")); - $from_id = $user->id; - $subject = $event->req_POST("subject"); - $message = $event->req_POST("message"); - send_event(new SendPMEvent(new PM($from_id, get_real_ip(), $to_id, $subject, $message))); - $page->flash("PM sent"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(referer_or(make_link())); - } - } - break; - default: - $this->theme->display_error(400, "Invalid action", "That's not something you can do with a PM"); - break; + if ($event->page_matches("pm/read", permission: Permissions::READ_PM)) { + $pm_id = int_escape($event->get_arg(1)); + $pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", ["id" => $pm_id]); + if (is_null($pm)) { + $this->theme->display_error(404, "No such PM", "There is no PM #$pm_id"); + } elseif (($pm["to_id"] == $user->id) || $user->can(Permissions::VIEW_OTHER_PMS)) { + $from_user = User::by_id((int)$pm["from_id"]); + if ($pm["to_id"] == $user->id) { + $database->execute("UPDATE private_message SET is_read=true WHERE id = :id", ["id" => $pm_id]); + $cache->delete("pm-count-{$user->id}"); + } + $pmo = PM::from_row($pm); + $this->theme->display_message($page, $from_user, $user, $pmo); + if($user->can(Permissions::SEND_PM)) { + $this->theme->display_composer($page, $user, $from_user, "Re: ".$pmo->subject); + } + } else { + throw new PermissionDeniedException("You do not have permission to view this PM"); } } + if ($event->page_matches("pm/delete", method: "POST", permission: Permissions::READ_PM)) { + $pm_id = int_escape($event->req_POST("pm_id")); + $pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", ["id" => $pm_id]); + if (is_null($pm)) { + $this->theme->display_error(404, "No such PM", "There is no PM #$pm_id"); + } elseif (($pm["to_id"] == $user->id) || $user->can(Permissions::VIEW_OTHER_PMS)) { + $database->execute("DELETE FROM private_message WHERE id = :id", ["id" => $pm_id]); + $cache->delete("pm-count-{$user->id}"); + log_info("pm", "Deleted PM #$pm_id", "PM deleted"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(referer_or(make_link())); + } + } + if ($event->page_matches("pm/send", method: "POST", permission: Permissions::SEND_PM)) { + $to_id = int_escape($event->req_POST("to_id")); + $from_id = $user->id; + $subject = $event->req_POST("subject"); + $message = $event->req_POST("message"); + send_event(new SendPMEvent(new PM($from_id, get_real_ip(), $to_id, $subject, $message))); + $page->flash("PM sent"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(referer_or(make_link())); + } } public function onSendPM(SendPMEvent $event): void diff --git a/ext/pools/main.php b/ext/pools/main.php index 3a6d1b99..1c8b84ca 100644 --- a/ext/pools/main.php +++ b/ext/pools/main.php @@ -93,14 +93,14 @@ class Pool */ public function __construct(array $row) { - $this->id = (int)$row['id']; - $this->user_id = (int)$row['user_id']; + $this->id = (int) $row['id']; + $this->user_id = (int) $row['user_id']; $this->user_name = $row['user_name'] ?? null; $this->public = bool_escape($row['public']); $this->title = $row['title']; $this->description = $row['description']; $this->date = $row['date']; - $this->posts = (int)$row['posts']; + $this->posts = (int) $row['posts']; } /** @@ -198,7 +198,7 @@ class Pools extends Extension // column non-deterministically, so let's check if it is there and // add it if needed. $cols = $database->raw_db()->describe("pools"); - if(!array_key_exists("lastupdated", $cols)) { + if (!array_key_exists("lastupdated", $cols)) { $database->execute("ALTER TABLE pools ADD COLUMN lastupdated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP"); } $this->set_version("ext_pools_version", 5); @@ -240,7 +240,7 @@ class Pools extends Extension if ($event->page_matches("pool/list")) { //index if ($event->get_GET('search')) { $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link('pool/list').'/'.url_escape($event->get_GET('search')).'/'.strval($event->try_page_num(1))); + $page->set_redirect(make_link('pool/list') . '/' . url_escape($event->get_GET('search')) . '/' . strval($event->try_page_num(1))); return; } if (count($event->args) >= 4) { // Assume first 2 args are search and page num @@ -251,232 +251,218 @@ class Pools extends Extension $page_num = $event->try_page_num(0); } $this->list_pools($page, $page_num, $search); - } elseif ($event->page_matches("pool")) { - // What action are we trying to perform? - switch ($event->get_arg(0)) { - case "new": // Show form for new pools - if (!$user->is_anonymous()) { - $this->theme->new_pool_composer($page); - } else { - $errMessage = "You must be registered and logged in to create a new pool."; - $this->theme->display_error(401, "Error", $errMessage); - } - break; + } + if ($event->page_matches("pool/new", method: "GET")) { + if (!$user->is_anonymous()) { + $this->theme->new_pool_composer($page); + } else { + $errMessage = "You must be registered and logged in to create a new pool."; + $this->theme->display_error(401, "Error", $errMessage); + } + } + if ($event->page_matches("pool/create", method: "POST")) { + try { + $pce = send_event( + new PoolCreationEvent( + $event->req_POST("title"), + $user, + bool_escape($event->req_POST("public")), + $event->req_POST("description") + ) + ); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("pool/view/" . $pce->new_id)); + } catch (PoolCreationException $e) { + $this->theme->display_error(400, "Error", $e->error); + } + } + if ($event->page_matches("pool/view", method: "GET")) { + $poolID = int_escape($event->get_arg(0)); + $this->get_posts($event->try_page_num(1), $poolID); + } + if ($event->page_matches("pool/updated")) { + $this->get_history($event->try_page_num(0)); + } + if ($event->page_matches("pool/revert")) { + if (!$user->is_anonymous()) { + $historyID = int_escape($event->get_arg(0)); + $this->revert_history($historyID); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("pool/updated")); + } + } + if ($event->page_matches("pool/edit")) { + $pool_id = int_escape($event->req_POST("pool_id")); + $pool = $this->get_single_pool($pool_id); - case "create": // ADD _POST - try { - $event = send_event(new PoolCreationEvent( - $event->req_POST("title"), - $user, - bool_escape($event->req_POST("public")), - $event->req_POST("description") - )); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("pool/view/" . $event->new_id)); - } catch (PoolCreationException $e) { - $this->theme->display_error(400, "Error", $e->error); - } - break; + if ($this->have_permission($user, $pool)) { + $result = $database->execute("SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", ["pid" => $pool_id]); + $images = []; + while ($row = $result->fetch()) { + $images[] = Image::by_id((int) $row["image_id"]); + } + $this->theme->edit_pool($page, $pool, $images); + } else { + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("pool/view/" . $pool_id)); + } + } + if ($event->page_matches("pool/order")) { + $pool_id = int_escape($event->req_POST("pool_id")); + $pool = $this->get_single_pool($pool_id); - case "view": - $poolID = int_escape($event->get_arg(1)); - $this->get_posts($event, $poolID); - break; + if ($event->get_POST("order_view")) { + if ($this->have_permission($user, $pool)) { + $result = $database->execute( + "SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", + ["pid" => $pool_id] + ); + $images = []; - case "updated": - $this->get_history($event->try_page_num(1)); - break; - - case "revert": - if (!$user->is_anonymous()) { - $historyID = int_escape($event->get_arg(1)); - $this->revert_history($historyID); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("pool/updated")); - } - break; - - case "edit": // Edit the pool (remove images) - $pool_id = int_escape($event->req_POST("pool_id")); - $pool = $this->get_single_pool($pool_id); - - if ($this->have_permission($user, $pool)) { - $result = $database->execute("SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", ["pid" => $pool_id]); - $images = []; - while ($row = $result->fetch()) { - $images[] = Image::by_id((int)$row["image_id"]); - } - $this->theme->edit_pool($page, $pool, $images); - } else { - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("pool/view/" . $pool_id)); - } - break; - - case "order": // Order the pool (view and change the order of images within the pool) - $pool_id = int_escape($event->req_POST("pool_id")); - $pool = $this->get_single_pool($pool_id); - - if ($event->get_POST("order_view")) { - if ($this->have_permission($user, $pool)) { - $result = $database->execute( - "SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", - ["pid" => $pool_id] - ); - $images = []; - - while ($row = $result->fetch()) { - $image = $database->get_row( - " - SELECT * FROM images AS i - INNER JOIN pool_images AS p ON i.id = p.image_id - WHERE pool_id=:pid AND i.id=:iid", - ["pid" => $pool_id, "iid" => (int)$row['image_id']] - ); - $images[] = ($image ? new Image($image) : null); - } - - $this->theme->edit_order($page, $pool, $images); - } else { - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("pool/view/" . $pool_id)); - } - } else { - if ($this->have_permission($user, $pool)) { - foreach ($event->POST as $key => $value) { - if(str_starts_with($key, "order_")) { - $imageID = (int)substr($key, 6); - $database->execute( - " - UPDATE pool_images - SET image_order = :ord - WHERE pool_id = :pid AND image_id = :iid", - ["ord" => $value, "pid" => int_escape($event->req_POST('pool_id')), "iid" => $imageID] - ); - } - } - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("pool/view/" . $pool_id)); - } else { - $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); - } - } - break; - case "reverse": - $pool_id = int_escape($event->req_POST("pool_id")); - $pool = $this->get_single_pool($pool_id); - - if ($this->have_permission($user, $pool)) { - $database->with_savepoint(function () use ($pool_id) { - global $database; - $result = $database->execute( - "SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order DESC", - ["pid" => $pool_id] - ); - $image_order = 1; - while ($row = $result->fetch()) { - $database->execute( - " - UPDATE pool_images - SET image_order=:ord - WHERE pool_id = :pid AND image_id = :iid", - ["ord" => $image_order, "pid" => $pool_id, "iid" => (int)$row['image_id']] - ); - $image_order = $image_order + 1; - } - }); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("pool/view/" . $pool_id)); - } else { - $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); - } - break; - case "import": - $pool_id = int_escape($event->req_POST("pool_id")); - $pool = $this->get_single_pool($pool_id); - - if ($this->have_permission($user, $pool)) { - $images = Search::find_images( - limit: $config->get_int(PoolsConfig::MAX_IMPORT_RESULTS, 1000), - tags: Tag::explode($event->req_POST("pool_tag")) + while ($row = $result->fetch()) { + $image = $database->get_row( + " + SELECT * FROM images AS i + INNER JOIN pool_images AS p ON i.id = p.image_id + WHERE pool_id=:pid AND i.id=:iid", + ["pid" => $pool_id, "iid" => (int) $row['image_id']] ); - $this->theme->pool_result($page, $images, $pool); - } else { - $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); + $images[] = ($image ? new Image($image) : null); } - break; - case "add_posts": - $pool_id = int_escape($event->req_POST("pool_id")); - $pool = $this->get_single_pool($pool_id); - - if ($this->have_permission($user, $pool)) { - $image_ids = array_map('intval', $event->req_POST_array('check')); - send_event(new PoolAddPostsEvent($pool_id, $image_ids)); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("pool/view/" . $pool_id)); - } else { - $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); - } - break; - - case "remove_posts": - $pool_id = int_escape($event->req_POST("pool_id")); - $pool = $this->get_single_pool($pool_id); - - if ($this->have_permission($user, $pool)) { - $images = ""; - foreach ($event->req_POST_array('check') as $imageID) { + $this->theme->edit_order($page, $pool, $images); + } else { + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("pool/view/" . $pool_id)); + } + } else { + if ($this->have_permission($user, $pool)) { + foreach ($event->POST as $key => $value) { + if (str_starts_with($key, "order_")) { + $imageID = (int) substr($key, 6); $database->execute( - "DELETE FROM pool_images WHERE pool_id = :pid AND image_id = :iid", - ["pid" => $pool_id, "iid" => $imageID] + " + UPDATE pool_images + SET image_order = :ord + WHERE pool_id = :pid AND image_id = :iid", + ["ord" => $value, "pid" => int_escape($event->req_POST('pool_id')), "iid" => $imageID] ); - $images .= " " . $imageID; } - $count = (int)$database->get_one( - "SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", - ["pid" => $pool_id] - ); - $this->add_history($pool_id, 0, $images, $count); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("pool/view/" . $pool_id)); - } else { - $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); } + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("pool/view/" . $pool_id)); + } else { + $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); + } + } + } + if ($event->page_matches("pool/reverse")) { + $pool_id = int_escape($event->req_POST("pool_id")); + $pool = $this->get_single_pool($pool_id); - break; - - case "edit_description": - $pool_id = int_escape($event->req_POST("pool_id")); - $pool = $this->get_single_pool($pool_id); - - if ($this->have_permission($user, $pool)) { + if ($this->have_permission($user, $pool)) { + $database->with_savepoint(function () use ($pool_id) { + global $database; + $result = $database->execute( + "SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order DESC", + ["pid" => $pool_id] + ); + $image_order = 1; + while ($row = $result->fetch()) { $database->execute( - "UPDATE pools SET description=:dsc,lastupdated=CURRENT_TIMESTAMP WHERE id=:pid", - ["dsc" => $event->req_POST('description'), "pid" => $pool_id] + " + UPDATE pool_images + SET image_order=:ord + WHERE pool_id = :pid AND image_id = :iid", + ["ord" => $image_order, "pid" => $pool_id, "iid" => (int) $row['image_id']] ); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("pool/view/" . $pool_id)); - } else { - $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); + $image_order = $image_order + 1; } + }); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("pool/view/" . $pool_id)); + } else { + $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); + } + } + if ($event->page_matches("pool/import")) { + $pool_id = int_escape($event->req_POST("pool_id")); + $pool = $this->get_single_pool($pool_id); - break; + if ($this->have_permission($user, $pool)) { + $images = Search::find_images( + limit: $config->get_int(PoolsConfig::MAX_IMPORT_RESULTS, 1000), + tags: Tag::explode($event->req_POST("pool_tag")) + ); + $this->theme->pool_result($page, $images, $pool); + } else { + $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); + } + } + if ($event->page_matches("pool/add_posts")) { + $pool_id = int_escape($event->req_POST("pool_id")); + $pool = $this->get_single_pool($pool_id); - case "nuke": - // Completely remove the given pool. - // -> Only admins and owners may do this - $pool_id = int_escape($event->req_POST("pool_id")); - $pool = $this->get_single_pool($pool_id); + if ($this->have_permission($user, $pool)) { + $image_ids = array_map('intval', $event->req_POST_array('check')); + send_event(new PoolAddPostsEvent($pool_id, $image_ids)); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("pool/view/" . $pool_id)); + } else { + $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); + } + } + if ($event->page_matches("pool/remove_posts")) { + $pool_id = int_escape($event->req_POST("pool_id")); + $pool = $this->get_single_pool($pool_id); - if ($user->can(Permissions::POOLS_ADMIN) || $user->id == $pool->user_id) { - send_event(new PoolDeletionEvent($pool_id)); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("pool/list")); - } else { - $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); - } - break; + if ($this->have_permission($user, $pool)) { + $images = ""; + foreach ($event->req_POST_array('check') as $imageID) { + $database->execute( + "DELETE FROM pool_images WHERE pool_id = :pid AND image_id = :iid", + ["pid" => $pool_id, "iid" => $imageID] + ); + $images .= " " . $imageID; + } + $count = (int) $database->get_one( + "SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", + ["pid" => $pool_id] + ); + $this->add_history($pool_id, 0, $images, $count); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("pool/view/" . $pool_id)); + } else { + $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); + } + } + if ($event->page_matches("pool/edit_description")) { + $pool_id = int_escape($event->req_POST("pool_id")); + $pool = $this->get_single_pool($pool_id); + + if ($this->have_permission($user, $pool)) { + $database->execute( + "UPDATE pools SET description=:dsc,lastupdated=CURRENT_TIMESTAMP WHERE id=:pid", + ["dsc" => $event->req_POST('description'), "pid" => $pool_id] + ); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("pool/view/" . $pool_id)); + } else { + $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); + } + } + if ($event->page_matches("pool/nuke")) { + // Completely remove the given pool. + // -> Only admins and owners may do this + $pool_id = int_escape($event->req_POST("pool_id")); + $pool = $this->get_single_pool($pool_id); + + if ($user->can(Permissions::POOLS_ADMIN) || $user->id == $pool->user_id) { + send_event(new PoolDeletionEvent($pool_id)); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("pool/list")); + } else { + $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); } } } @@ -587,19 +573,19 @@ class Pools extends Extension $matches = []; if (preg_match("/^pool[=|:]([^:]*|lastcreated):?([0-9]*)$/i", $event->term, $matches)) { global $user; - $poolTag = (string)str_replace("_", " ", $matches[1]); + $poolTag = (string) str_replace("_", " ", $matches[1]); $pool = null; if ($poolTag == 'lastcreated') { $pool = $this->get_last_userpool($user->id); } elseif (ctype_digit($poolTag)) { //If only digits, assume PoolID - $pool = $this->get_single_pool((int)$poolTag); + $pool = $this->get_single_pool((int) $poolTag); } else { //assume PoolTitle $pool = $this->get_single_pool_from_title($poolTag); } if ($pool && $this->have_permission($user, $pool)) { - $image_order = (int)($matches[2] ?: 0); + $image_order = (int) ($matches[2] ?: 0); $this->add_post($pool->id, $event->image_id, true, $image_order); } } @@ -612,8 +598,8 @@ class Pools extends Extension $options = $database->get_pairs("SELECT id,title FROM pools ORDER BY title"); // TODO: Don't cast into strings, make BABBE accept HTMLElement instead. - $event->add_action("bulk_pool_add_existing", "Add To (P)ool", "p", "", (string)$this->theme->get_bulk_pool_selector($options)); - $event->add_action("bulk_pool_add_new", "Create Pool", "", "", (string)$this->theme->get_bulk_pool_input($event->search_terms)); + $event->add_action("bulk_pool_add_existing", "Add To (P)ool", "p", "", (string) $this->theme->get_bulk_pool_selector($options)); + $event->add_action("bulk_pool_add_new", "Create Pool", "", "", (string) $this->theme->get_bulk_pool_input($event->search_terms)); } public function onBulkAction(BulkActionEvent $event): void @@ -680,7 +666,7 @@ class Pools extends Extension $where_clause = "WHERE LOWER(title) like '%%'"; if ($search != null) { - $where_clause = "WHERE LOWER(title) like '%".strtolower($search)."%'"; + $where_clause = "WHERE LOWER(title) like '%" . strtolower($search) . "%'"; } $pools = array_map([Pool::class, "makePool"], $database->get_all(" @@ -692,7 +678,7 @@ class Pools extends Extension $order_by LIMIT :l OFFSET :o ", ["l" => $poolsPerPage, "o" => $pageNumber * $poolsPerPage])); - $totalPages = (int)ceil((int)$database->get_one("SELECT COUNT(*) FROM pools ".$where_clause) / $poolsPerPage); + $totalPages = (int) ceil((int) $database->get_one("SELECT COUNT(*) FROM pools " . $where_clause) / $poolsPerPage); $this->theme->list_pools($page, $pools, $search, $pageNumber + 1, $totalPages); } @@ -784,7 +770,7 @@ class Pools extends Extension } if (count($images) > 0) { - $count = (int)$database->get_one( + $count = (int) $database->get_one( "SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $event->pool_id] ); @@ -839,11 +825,10 @@ class Pools extends Extension /** * Retrieve all the images in a pool, given a pool ID. */ - private function get_posts(PageRequestEvent $event, int $poolID): void + private function get_posts(int $pageNumber, int $poolID): void { global $config, $user, $database; - $pageNumber = $event->try_page_num(2); $pool = $this->get_single_pool($poolID); $imagesPerPage = $config->get_int(PoolsConfig::IMAGES_PER_PAGE); @@ -856,7 +841,7 @@ class Pools extends Extension // WE CHECK IF THE EXTENSION RATING IS INSTALLED, WHICH VERSION AND IF IT // WORKS TO SHOW/HIDE SAFE, QUESTIONABLE, EXPLICIT AND UNRATED IMAGES FROM USER if (Extension::is_enabled(RatingsInfo::KEY)) { - $query .= "AND i.rating IN (".Ratings::privs_to_sql(Ratings::get_user_class_privs($user)).")"; + $query .= "AND i.rating IN (" . Ratings::privs_to_sql(Ratings::get_user_class_privs($user)) . ")"; } if (Extension::is_enabled(TrashInfo::KEY)) { $query .= " AND trash != :true"; @@ -876,14 +861,14 @@ class Pools extends Extension ] + $params ); - $totalPages = (int)ceil((int)$database->get_one( + $totalPages = (int) ceil((int) $database->get_one( "SELECT COUNT(*) FROM pool_images p $query", ["pid" => $poolID] + $params ) / $imagesPerPage); $images = []; foreach ($result as $singleResult) { - $images[] = Image::by_id((int)$singleResult["image_id"]); + $images[] = Image::by_id((int) $singleResult["image_id"]); } $this->theme->view_pool($pool, $images, $pageNumber + 1, $totalPages); @@ -897,7 +882,7 @@ class Pools extends Extension global $user, $database; $poolID = $event->pool_id; - $owner_id = (int)$database->get_one("SELECT user_id FROM pools WHERE id = :pid", ["pid" => $poolID]); + $owner_id = (int) $database->get_one("SELECT user_id FROM pools WHERE id = :pid", ["pid" => $poolID]); if ($owner_id == $user->id || $user->can(Permissions::POOLS_ADMIN)) { $database->execute("DELETE FROM pool_history WHERE pool_id = :pid", ["pid" => $poolID]); $database->execute("DELETE FROM pool_images WHERE pool_id = :pid", ["pid" => $poolID]); @@ -940,7 +925,7 @@ class Pools extends Extension LIMIT :l OFFSET :o ", ["l" => $historiesPerPage, "o" => $pageNumber * $historiesPerPage]); - $totalPages = (int)ceil((int)$database->get_one("SELECT COUNT(*) FROM pool_history") / $historiesPerPage); + $totalPages = (int) ceil((int) $database->get_one("SELECT COUNT(*) FROM pool_history") / $historiesPerPage); $this->theme->show_history($history, $pageNumber + 1, $totalPages); } @@ -956,7 +941,7 @@ class Pools extends Extension foreach ($status as $entry) { $images = trim($entry['images']); $images = explode(" ", $images); - $poolID = (int)$entry['pool_id']; + $poolID = (int) $entry['pool_id']; $imageArray = ""; $newAction = -1; @@ -985,7 +970,7 @@ class Pools extends Extension continue; // go on to the next one. } - $count = (int)$database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $poolID]); + $count = (int) $database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $poolID]); $this->add_history($poolID, $newAction, $imageArray, $count); } } @@ -998,14 +983,14 @@ class Pools extends Extension { global $database, $config; - $result = (int)$database->get_one( + $result = (int) $database->get_one( "SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid AND image_id=:iid", ["pid" => $poolID, "iid" => $imageID] ); if ($result == 0) { if ($config->get_bool(PoolsConfig::AUTO_INCREMENT_ORDER) && $imageOrder === 0) { - $imageOrder = (int)$database->get_one( + $imageOrder = (int) $database->get_one( " SELECT COALESCE(MAX(image_order),0) + 1 FROM pool_images @@ -1028,8 +1013,8 @@ class Pools extends Extension $this->update_count($poolID); if ($history) { - $count = (int)$database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $poolID]); - $this->add_history($poolID, 1, (string)$imageID, $count); + $count = (int) $database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $poolID]); + $this->add_history($poolID, 1, (string) $imageID, $count); } return true; } diff --git a/ext/private_image/main.php b/ext/private_image/main.php index a8502162..b31586ff 100644 --- a/ext/private_image/main.php +++ b/ext/private_image/main.php @@ -43,7 +43,7 @@ class PrivateImage extends Extension { global $page, $user, $user_config; - if ($event->page_matches("privatize_image") && $user->can(Permissions::SET_PRIVATE_IMAGE)) { + if ($event->page_matches("privatize_image", method: "POST", permission: Permissions::SET_PRIVATE_IMAGE)) { // Try to get the image ID $image_id = int_escape(null_throws($event->get_arg(0))); $image = Image::by_id($image_id); @@ -59,7 +59,7 @@ class PrivateImage extends Extension $page->set_redirect(make_link("post/view/" . $image_id)); } - if ($event->page_matches("publicize_image")) { + if ($event->page_matches("publicize_image", method: "POST")) { // Try to get the image ID $image_id = int_escape(null_throws($event->get_arg(0))); $image = Image::by_id($image_id); @@ -75,29 +75,22 @@ class PrivateImage extends Extension $page->set_redirect(make_link("post/view/".$image_id)); } - if ($event->page_matches("user_admin")) { - if (!$user->check_auth_token()) { - return; + if ($event->page_matches("user_admin/private_image", method: "POST")) { + $id = int_escape($event->req_POST('id')); + if ($id != $user->id) { + throw new SCoreException("Cannot change another user's settings"); } - switch ($event->get_arg(0)) { - case "private_image": - $id = int_escape($event->req_POST('id')); - if ($id != $user->id) { - throw new SCoreException("Cannot change another user's settings"); - } - $set_default = array_key_exists("set_default", $event->POST); - $view_default = array_key_exists("view_default", $event->POST); + $set_default = array_key_exists("set_default", $event->POST); + $view_default = array_key_exists("view_default", $event->POST); - $user_config->set_bool(PrivateImageConfig::USER_SET_DEFAULT, $set_default); - $user_config->set_bool(PrivateImageConfig::USER_VIEW_DEFAULT, $view_default); + $user_config->set_bool(PrivateImageConfig::USER_SET_DEFAULT, $set_default); + $user_config->set_bool(PrivateImageConfig::USER_VIEW_DEFAULT, $view_default); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("user")); - - break; - } + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("user")); } } + public function onDisplayingImage(DisplayingImageEvent $event): void { global $user, $page; @@ -108,7 +101,6 @@ class PrivateImage extends Extension } } - public const SEARCH_REGEXP = "/^private:(yes|no|any)/"; public function onSearchTermParse(SearchTermParseEvent $event): void { diff --git a/ext/rating/main.php b/ext/rating/main.php index cc6f19a7..8b7a4761 100644 --- a/ext/rating/main.php +++ b/ext/rating/main.php @@ -374,27 +374,23 @@ class Ratings extends Extension { global $user, $page; - if ($event->page_matches("admin/bulk_rate")) { - if (!$user->can(Permissions::BULK_EDIT_IMAGE_RATING)) { - throw new PermissionDeniedException("Permission denied"); - } else { - $n = 0; - while (true) { - $images = Search::find_images($n, 100, Tag::explode($event->req_POST("query"))); - if (count($images) == 0) { - break; - } - - reset($images); // rewind to first element in array. - - foreach ($images as $image) { - send_event(new RatingSetEvent($image, $event->req_POST('rating'))); - } - $n += 100; + if ($event->page_matches("admin/bulk_rate", method: "POST", permission: Permissions::BULK_EDIT_IMAGE_RATING)) { + $n = 0; + while (true) { + $images = Search::find_images($n, 100, Tag::explode($event->req_POST("query"))); + if (count($images) == 0) { + break; } - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link()); + + reset($images); // rewind to first element in array. + + foreach ($images as $image) { + send_event(new RatingSetEvent($image, $event->req_POST('rating'))); + } + $n += 100; } + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link()); } } diff --git a/ext/regen_thumb/main.php b/ext/regen_thumb/main.php index bd05b165..28cc18c5 100644 --- a/ext/regen_thumb/main.php +++ b/ext/regen_thumb/main.php @@ -21,8 +21,8 @@ class RegenThumb extends Extension { global $page, $user; - if ($event->page_matches("regen_thumb") && $user->can(Permissions::DELETE_IMAGE)) { - if ($event->authed_page_matches("regen_thumb/one")) { + if ($event->page_matches("regen_thumb", method: "POST", permission: Permissions::DELETE_IMAGE)) { + if ($event->page_matches("regen_thumb/one")) { $image = Image::by_id(int_escape($event->get_arg(0))); $this->regenerate_thumbnail($image); diff --git a/ext/replace_file/main.php b/ext/replace_file/main.php index da5aab70..c60791a8 100644 --- a/ext/replace_file/main.php +++ b/ext/replace_file/main.php @@ -13,12 +13,7 @@ class ReplaceFile extends Extension { global $cache, $page, $user; - if ($event->page_matches("replace")) { - if (!$user->can(Permissions::REPLACE_IMAGE)) { - $this->theme->display_error(403, "Error", "{$user->name} doesn't have permission to replace images"); - return; - } - + if ($event->page_matches("replace", permission: Permissions::REPLACE_IMAGE)) { $image_id = int_escape($event->get_arg(0)); $image = Image::by_id($image_id); if (is_null($image)) { @@ -28,6 +23,7 @@ class ReplaceFile extends Extension if($event->method == "GET") { $this->theme->display_replace_page($page, $image_id); } elseif($event->method == "POST") { + $user->ensure_authed(); if (!empty($event->get_POST("url"))) { $tmp_filename = shm_tempnam("transload"); fetch_url($event->req_POST("url"), $tmp_filename); diff --git a/ext/report_image/main.php b/ext/report_image/main.php index b3287daa..65432d64 100644 --- a/ext/report_image/main.php +++ b/ext/report_image/main.php @@ -52,27 +52,24 @@ class ReportImage extends Extension { global $page, $user; if ($event->page_matches("image_report")) { - if ($event->get_arg(0) == "add") { + if ($event->page_matches("image_report/add")) { $image_id = int_escape($event->req_POST('image_id')); send_event(new AddReportedImageEvent(new ImageReport($image_id, $user->id, $event->req_POST('reason')))); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/$image_id")); - } elseif ($event->get_arg(0) == "remove") { - if ($user->can(Permissions::VIEW_IMAGE_REPORT)) { - send_event(new RemoveReportedImageEvent(int_escape($event->req_POST('id')))); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("image_report/list")); - } - } elseif ($event->get_arg(0) == "remove_reports_by" && $user->check_auth_token()) { - if ($user->can(Permissions::VIEW_IMAGE_REPORT)) { - $this->delete_reports_by(int_escape($event->req_POST('user_id'))); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link()); - } - } elseif ($event->get_arg(0) == "list") { - if ($user->can(Permissions::VIEW_IMAGE_REPORT)) { - $this->theme->display_reported_images($page, $this->get_reported_images()); - } + } + if ($event->page_matches("image_report/remove", method: "POST", permission: Permissions::VIEW_IMAGE_REPORT)) { + send_event(new RemoveReportedImageEvent(int_escape($event->req_POST('id')))); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("image_report/list")); + } + if ($event->page_matches("image_report/remove_reports_by", method: "POST", permission: Permissions::VIEW_IMAGE_REPORT)) { + $this->delete_reports_by(int_escape($event->req_POST('user_id'))); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link()); + } + if ($event->page_matches("image_report/list", permission: Permissions::VIEW_IMAGE_REPORT)) { + $this->theme->display_reported_images($page, $this->get_reported_images()); } } } diff --git a/ext/resize/main.php b/ext/resize/main.php index 9c4a234e..1dfa1ff8 100644 --- a/ext/resize/main.php +++ b/ext/resize/main.php @@ -141,7 +141,7 @@ class ResizeImage extends Extension { global $page, $user; - if ($event->authed_page_matches("resize") && $user->can(Permissions::EDIT_FILES)) { + if ($event->page_matches("resize", method: "POST", permission: Permissions::EDIT_FILES)) { // Try to get the image ID $image_id = int_escape(null_throws($event->get_arg(0))); $image = Image::by_id($image_id); diff --git a/ext/rotate/main.php b/ext/rotate/main.php index 119e03ac..13208af6 100644 --- a/ext/rotate/main.php +++ b/ext/rotate/main.php @@ -59,7 +59,7 @@ class RotateImage extends Extension { global $page, $user; - if ($event->authed_page_matches("rotate") && $user->can(Permissions::EDIT_FILES)) { + if ($event->page_matches("rotate", method: "POST", permission: Permissions::EDIT_FILES)) { // Try to get the image ID $image_id = int_escape(null_throws($event->get_arg(0))); $image = Image::by_id($image_id); diff --git a/ext/s3/main.php b/ext/s3/main.php index e14fb247..a6de1675 100644 --- a/ext/s3/main.php +++ b/ext/s3/main.php @@ -129,10 +129,7 @@ class S3 extends Extension public function onPageRequest(PageRequestEvent $event): void { global $config, $page, $user; - if ( - $event->authed_page_matches("s3/sync") && - $user->can(Permissions::DELETE_IMAGE) - ) { + if ($event->page_matches("s3/sync", method: "POST", permission: Permissions::DELETE_IMAGE)) { $id = int_escape($event->get_arg(0)); $this->sync_post(Image::by_id($id)); log_info("s3", "Manual resync for >>$id", "File re-sync'ed"); diff --git a/ext/setup/main.php b/ext/setup/main.php index 795eb641..a0706288 100644 --- a/ext/setup/main.php +++ b/ext/setup/main.php @@ -336,23 +336,19 @@ class Setup extends Extension $page->set_data("ok"); } - if ($event->page_matches("setup")) { - if (!$user->can(Permissions::CHANGE_SETTING)) { - $this->theme->display_permission_denied(); - } else { - if ($event->count_args() == 0) { - $panel = new SetupPanel($config); - send_event(new SetupBuildingEvent($panel)); - $this->theme->display_page($page, $panel); - } elseif ($event->get_arg(0) == "save" && $user->check_auth_token()) { - send_event(new ConfigSaveEvent($config, $event->POST)); - $config->save(); - $page->flash("Config saved"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("setup")); - } elseif ($event->get_arg(0) == "advanced") { - $this->theme->display_advanced($page, $config->values); - } + if ($event->page_matches("setup", permission: Permissions::CHANGE_SETTING)) { + if ($event->count_args() == 0) { + $panel = new SetupPanel($config); + send_event(new SetupBuildingEvent($panel)); + $this->theme->display_page($page, $panel); + } elseif ($event->get_arg(0) == "save" && $user->check_auth_token()) { + send_event(new ConfigSaveEvent($config, $event->POST)); + $config->save(); + $page->flash("Config saved"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("setup")); + } elseif ($event->get_arg(0) == "advanced") { + $this->theme->display_advanced($page, $config->values); } } } diff --git a/ext/setup/test.php b/ext/setup/test.php index f732efb7..5d7ef20d 100644 --- a/ext/setup/test.php +++ b/ext/setup/test.php @@ -18,17 +18,17 @@ class SetupTest extends ShimmiePHPUnitTestCase public function testAuthAnon(): void { - $this->get_page('setup'); - $this->assert_response(403); - $this->assert_title("Permission Denied"); + $this->assertException(PermissionDeniedException::class, function () { + $this->get_page('setup'); + }); } public function testAuthUser(): void { $this->log_in_as_user(); - $this->get_page('setup'); - $this->assert_response(403); - $this->assert_title("Permission Denied"); + $this->assertException(PermissionDeniedException::class, function () { + $this->get_page('setup'); + }); } public function testAuthAdmin(): void diff --git a/ext/source_history/main.php b/ext/source_history/main.php index c05d498a..16416907 100644 --- a/ext/source_history/main.php +++ b/ext/source_history/main.php @@ -32,15 +32,11 @@ class SourceHistory extends Extension { global $page, $user; - if ($event->page_matches("source_history/revert")) { + if ($event->page_matches("source_history/revert", method: "POST", permission: Permissions::EDIT_IMAGE_TAG)) { // this is a request to revert to a previous version of the source - if ($user->can(Permissions::EDIT_IMAGE_TAG)) { - $this->process_revert_request((int)$event->req_POST('revert')); - } - } elseif ($event->page_matches("source_history/bulk_revert")) { - if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG) && $user->check_auth_token()) { - $this->process_bulk_revert_request(); - } + $this->process_revert_request((int)$event->req_POST('revert')); + } elseif ($event->page_matches("source_history/bulk_revert", method: "POST", permission: Permissions::BULK_EDIT_IMAGE_TAG)) { + $this->process_bulk_revert_request(); } elseif ($event->page_matches("source_history/all")) { $page_id = int_escape($event->get_arg(0)); $this->theme->display_global_page($page, $this->get_global_source_history($page_id), $page_id); diff --git a/ext/tag_categories/main.php b/ext/tag_categories/main.php index d6718321..88388f00 100644 --- a/ext/tag_categories/main.php +++ b/ext/tag_categories/main.php @@ -69,11 +69,11 @@ class TagCategories extends Extension { global $database, $page, $user; - if ($event->page_matches("tags/categories")) { - if ($user->can(Permissions::EDIT_TAG_CATEGORIES)) { - $this->page_update(); - $this->theme->show_tag_categories($page, $database->get_all('SELECT * FROM image_tag_categories')); - } + if ($event->page_matches("tags/categories", method: "GET")) { + $this->theme->show_tag_categories($page, $database->get_all('SELECT * FROM image_tag_categories')); + } + if ($event->page_matches("tags/categories", method: "POST", permission: Permissions::EDIT_TAG_CATEGORIES)) { + $this->page_update(); } } diff --git a/ext/tag_edit/main.php b/ext/tag_edit/main.php index 3b789a30..3c5bced1 100644 --- a/ext/tag_edit/main.php +++ b/ext/tag_edit/main.php @@ -146,22 +146,18 @@ class TagEdit extends Extension public function onPageRequest(PageRequestEvent $event): void { global $user, $page; - if ($event->page_matches("tag_edit")) { + if ($event->page_matches("tag_edit", method: "POST", permission: Permissions::MASS_TAG_EDIT)) { if ($event->get_arg(0) == "replace") { - if ($user->can(Permissions::MASS_TAG_EDIT)) { - $search = $event->req_POST('search'); - $replace = $event->req_POST('replace'); - $this->mass_tag_edit($search, $replace, true); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("admin")); - } + $search = $event->req_POST('search'); + $replace = $event->req_POST('replace'); + $this->mass_tag_edit($search, $replace, true); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("admin")); } if ($event->get_arg(0) == "mass_source_set") { - if ($user->can(Permissions::MASS_TAG_EDIT)) { - $this->mass_source_edit($event->req_POST('tags'), $event->req_POST('source')); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(search_link()); - } + $this->mass_source_edit($event->req_POST('tags'), $event->req_POST('source')); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(search_link()); } } } diff --git a/ext/tag_history/main.php b/ext/tag_history/main.php index 601ed7d3..aa001851 100644 --- a/ext/tag_history/main.php +++ b/ext/tag_history/main.php @@ -26,15 +26,11 @@ class TagHistory extends Extension { global $page, $user; - if ($event->page_matches("tag_history/revert")) { + if ($event->page_matches("tag_history/revert", method: "POST", permission: Permissions::EDIT_IMAGE_TAG)) { // this is a request to revert to a previous version of the tags - if ($user->can(Permissions::EDIT_IMAGE_TAG)) { - $this->process_revert_request((int)$event->req_POST('revert')); - } - } elseif ($event->page_matches("tag_history/bulk_revert")) { - if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG) && $user->check_auth_token()) { - $this->process_bulk_revert_request(); - } + $this->process_revert_request((int)$event->req_POST('revert')); + } elseif ($event->page_matches("tag_history/bulk_revert", method: "POST", permission: Permissions::BULK_EDIT_IMAGE_TAG)) { + $this->process_bulk_revert_request(); } elseif ($event->page_matches("tag_history/all")) { $page_id = int_escape($event->get_arg(0)); $this->theme->display_global_page($page, $this->get_global_tag_history($page_id), $page_id); diff --git a/ext/tips/main.php b/ext/tips/main.php index b5927c6f..7139541d 100644 --- a/ext/tips/main.php +++ b/ext/tips/main.php @@ -67,38 +67,32 @@ class Tips extends Extension $this->getTip(); - if ($event->page_matches("tips") && $user->can(Permissions::TIPS_ADMIN)) { - switch ($event->get_arg(0)) { - case "list": - $this->manageTips(); - $this->getAll(); - break; - case "save": - if ($user->check_auth_token()) { - send_event(new CreateTipEvent( - $event->get_POST("enable") == "on", - $event->req_POST("image"), - $event->req_POST("text") - )); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("tips/list")); - } - break; - case "status": - // FIXME: HTTP GET CSRF - $tipID = int_escape($event->get_arg(1)); - $this->setStatus($tipID); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("tips/list")); - break; - case "delete": - // FIXME: HTTP GET CSRF - $tipID = int_escape($event->get_arg(1)); - send_event(new DeleteTipEvent($tipID)); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("tips/list")); - break; - } + if ($event->page_matches("tips/list", permission: Permissions::TIPS_ADMIN)) { + $this->manageTips(); + $this->getAll(); + } + if ($event->page_matches("tips/save", method: "POST", permission: Permissions::TIPS_ADMIN)) { + send_event(new CreateTipEvent( + $event->get_POST("enable") == "on", + $event->req_POST("image"), + $event->req_POST("text") + )); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("tips/list")); + } + if ($event->page_matches("tips/status", permission: Permissions::TIPS_ADMIN)) { + // FIXME: HTTP GET CSRF + $tipID = int_escape($event->get_arg(1)); + $this->setStatus($tipID); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("tips/list")); + } + if ($event->page_matches("tips/delete", permission: Permissions::TIPS_ADMIN)) { + // FIXME: HTTP GET CSRF + $tipID = int_escape($event->get_arg(1)); + send_event(new DeleteTipEvent($tipID)); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("tips/list")); } } diff --git a/ext/transcode/main.php b/ext/transcode/main.php index 79e8ac76..ed9b7e33 100644 --- a/ext/transcode/main.php +++ b/ext/transcode/main.php @@ -207,7 +207,7 @@ class TranscodeImage extends Extension { global $page, $user; - if ($event->page_matches("transcode") && $user->can(Permissions::EDIT_FILES)) { + if ($event->page_matches("transcode", method: "POST", permission: Permissions::EDIT_FILES)) { $image_id = int_escape($event->get_arg(0)); $image_obj = Image::by_id($image_id); if (is_null($image_obj)) { diff --git a/ext/transcode_video/main.php b/ext/transcode_video/main.php index a9a4d6d8..51618590 100644 --- a/ext/transcode_video/main.php +++ b/ext/transcode_video/main.php @@ -101,7 +101,7 @@ class TranscodeVideo extends Extension { global $page, $user; - if ($event->page_matches("transcode_video") && $user->can(Permissions::EDIT_FILES)) { + if ($event->page_matches("transcode_video", method: "POST", permission: Permissions::EDIT_FILES)) { $image_id = int_escape($event->get_arg(0)); $image_obj = Image::by_id($image_id); if (is_null($image_obj)) { diff --git a/ext/trash/main.php b/ext/trash/main.php index a945612e..ae069ede 100644 --- a/ext/trash/main.php +++ b/ext/trash/main.php @@ -29,7 +29,7 @@ class Trash extends Extension { global $page, $user; - if ($event->page_matches("trash_restore") && $user->can(Permissions::VIEW_TRASH)) { + if ($event->page_matches("trash_restore", method: "POST", permission: Permissions::VIEW_TRASH)) { $image_id = int_escape(null_throws($event->get_arg(0))); self::set_trash($image_id, false); $page->set_mode(PageMode::REDIRECT); diff --git a/ext/update/main.php b/ext/update/main.php index dc72358c..bf3c8a30 100644 --- a/ext/update/main.php +++ b/ext/update/main.php @@ -36,27 +36,29 @@ class Update extends Extension global $user, $page; $sha = $event->get_GET('sha'); - if ($user->can(Permissions::EDIT_FILES) && $sha) { - if ($event->page_matches("update/download")) { - $ok = $this->download_shimmie($sha); + // FIXME: use POST + if ($event->page_matches("update/download", permission: Permissions::EDIT_FILES)) { + assert(!is_null($sha)); + $ok = $this->download_shimmie($sha); - $page->set_mode(PageMode::REDIRECT); - if ($ok) { - $page->set_redirect(make_link("update/update", "sha=".$sha)); - } else { - $page->set_redirect(make_link("admin")); - } //TODO: Show error? - } elseif ($event->page_matches("update/update")) { - $ok = $this->update_shimmie($sha); + $page->set_mode(PageMode::REDIRECT); + if ($ok) { + $page->set_redirect(make_link("update/update", "sha=".$sha)); + } else { + $page->set_redirect(make_link("admin")); + } //TODO: Show error? + } + if ($event->page_matches("update/update", permission: Permissions::EDIT_FILES)) { + assert(!is_null($sha)); + $ok = $this->update_shimmie($sha); - $page->set_mode(PageMode::REDIRECT); - if ($ok) { - $page->set_redirect(make_link("admin")); - } //TODO: Show success? - else { - $page->set_redirect(make_link("admin")); - } //TODO: Show error? - } + $page->set_mode(PageMode::REDIRECT); + if ($ok) { + $page->set_redirect(make_link("admin")); + } //TODO: Show success? + else { + $page->set_redirect(make_link("admin")); + } //TODO: Show error? } } diff --git a/ext/upload/main.php b/ext/upload/main.php index 997eb740..8242ee27 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -216,11 +216,7 @@ class Upload extends Extension } } - if ($event->page_matches("upload")) { - if (!$user->can(Permissions::CREATE_IMAGE)) { - $this->theme->display_error(403, "Error", "{$user->name} doesn't have permission to upload images"); - return; - } + if ($event->page_matches("upload", permission: Permissions::CREATE_IMAGE)) { if ($this->is_full) { $this->theme->display_error(507, "Error", "Can't upload images: disk nearly full"); return; diff --git a/ext/user/main.php b/ext/user/main.php index f7df6d89..5b83e652 100644 --- a/ext/user/main.php +++ b/ext/user/main.php @@ -165,92 +165,154 @@ class UserPage extends Extension if ($user->can(Permissions::VIEW_HELLBANNED)) { $page->add_html_header(""); - } elseif(!$user->can(Permissions::HELLBANNED)) { + } elseif (!$user->can(Permissions::HELLBANNED)) { $page->add_html_header(""); } - if ($event->page_matches("user_admin")) { - if ($event->get_arg(0) == "login") { - if ($event->method == "POST") { - $this->page_login($event->req_POST('user'), $event->req_POST('pass')); - } else { - $this->theme->display_login_page($page); - } - } elseif ($event->get_arg(0) == "recover") { - $this->page_recover($event->req_POST('username')); - } elseif ($event->get_arg(0) == "create") { - $this->page_create($event); - } elseif ($event->get_arg(0) == "create_other") { - send_event(new UserCreationEvent( + if ($event->page_matches("user_admin/login", method: "GET")) { + $this->theme->display_login_page($page); + } + if ($event->page_matches("user_admin/login", method: "POST", authed: false)) { + $this->page_login($event->req_POST('user'), $event->req_POST('pass')); + } + if ($event->page_matches("user_admin/recover", method: "POST")) { + $this->page_recover($event->req_POST('username')); + } + if ($event->page_matches("user_admin/create", method: "GET", permission: Permissions::CREATE_USER)) { + global $config, $page, $user; + if (!$config->get_bool("login_signup_enabled")) { + $this->theme->display_signups_disabled($page); + return; + } + $this->theme->display_signup_page($page); + } + if ($event->page_matches("user_admin/create", method: "POST", authed: false, permission: Permissions::CREATE_USER)) { + global $config, $page, $user; + if (!$config->get_bool("login_signup_enabled")) { + $this->theme->display_signups_disabled($page); + return; + } + try { + $uce = send_event( + new UserCreationEvent( + $event->req_POST('name'), + $event->req_POST('pass1'), + $event->req_POST('pass2'), + $event->req_POST('email'), + true + ) + ); + $this->set_login_cookie($uce->username); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("user")); + } catch (UserCreationException $ex) { + $this->theme->display_error(400, "User Creation Error", $ex->getMessage()); + } + } + if ($event->page_matches("user_admin/create_other", method: "POST", permission: Permissions::CREATE_OTHER_USER)) { + send_event( + new UserCreationEvent( $event->req_POST("name"), $event->req_POST("pass1"), $event->req_POST("pass1"), $event->req_POST("email"), false - )); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("admin")); - $page->flash("Created new user"); - } elseif ($event->get_arg(0) == "list") { - $t = new UserTable($database->raw_db()); - $t->token = $user->get_auth_token(); - $t->inputs = $event->GET; - if ($user->can(Permissions::DELETE_USER)) { - $col = new TextColumn("email", "Email"); - // $t->columns[] = $col; - array_splice($t->columns, 2, 0, [$col]); - } - $this->theme->display_crud("Users", $t->table($t->query()), $t->paginator()); - } elseif ($event->get_arg(0) == "classes") { - $this->theme->display_user_classes( - $page, - UserClass::$known_classes, - (new \ReflectionClass(Permissions::class))->getReflectionConstants() - ); - } elseif ($event->get_arg(0) == "logout") { - $this->page_logout(); + ) + ); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("admin")); + $page->flash("Created new user"); + } + if ($event->page_matches("user_admin/list", method: "GET")) { + $t = new UserTable($database->raw_db()); + $t->token = $user->get_auth_token(); + $t->inputs = $event->GET; + if ($user->can(Permissions::DELETE_USER)) { + $col = new TextColumn("email", "Email"); + // $t->columns[] = $col; + array_splice($t->columns, 2, 0, [$col]); } + $this->theme->display_crud("Users", $t->table($t->query()), $t->paginator()); + } + if ($event->page_matches("user_admin/classes", method: "GET")) { + $this->theme->display_user_classes( + $page, + UserClass::$known_classes, + (new \ReflectionClass(Permissions::class))->getReflectionConstants() + ); + } + if ($event->page_matches("user_admin/logout", method: "GET")) { + // FIXME: security + $this->page_logout(); + } - if (!$user->check_auth_token()) { - return; - } elseif ($event->get_arg(0) == "change_name") { - $input = validate_input([ - 'id' => 'user_id,exists', - 'name' => 'user_name', - ]); - $duser = User::by_id($input['id']); - $this->change_name_wrapper($duser, $input['name']); - } elseif ($event->get_arg(0) == "change_pass") { - $input = validate_input([ - 'id' => 'user_id,exists', - 'pass1' => 'password', - 'pass2' => 'password', - ]); - $duser = User::by_id($input['id']); - $this->change_password_wrapper($duser, $input['pass1'], $input['pass2']); - } elseif ($event->get_arg(0) == "change_email") { - $input = validate_input([ - 'id' => 'user_id,exists', - 'address' => 'email', - ]); - $duser = User::by_id($input['id']); - $this->change_email_wrapper($duser, $input['address']); - } elseif ($event->get_arg(0) == "change_class") { - $input = validate_input([ - 'id' => 'user_id,exists', - 'class' => 'user_class', - ]); - $duser = User::by_id($input['id']); - $this->change_class_wrapper($duser, $input['class']); - } elseif ($event->get_arg(0) == "delete_user") { - $this->delete_user( - $page, - int_escape($event->req_POST('id')), - $event->get_POST("with_images") == "on", - $event->get_POST("with_comments") == "on" - ); + if ($event->page_matches("user_admin/change_name", method: "POST", permission: Permissions::EDIT_USER_NAME)) { + $input = validate_input([ + 'id' => 'user_id,exists', + 'name' => 'user_name', + ]); + $duser = User::by_id($input['id']); + if ($this->user_can_edit_user($user, $duser)) { + $duser->set_name($input['name']); + $page->flash("Username changed"); + // TODO: set login cookie if user changed themselves + $this->redirect_to_user($duser); } } + if ($event->page_matches("user_admin/change_pass", method: "POST")) { + $input = validate_input([ + 'id' => 'user_id,exists', + 'pass1' => 'password', + 'pass2' => 'password', + ]); + $duser = User::by_id($input['id']); + if ($this->user_can_edit_user($user, $duser)) { + if ($input['pass1'] != $input['pass2']) { + throw new UserErrorException("Passwords don't match"); + } else { + // FIXME: send_event() + $duser->set_password($input['pass1']); + if ($duser->id == $user->id) { + $this->set_login_cookie($duser->name); + } + $page->flash("Password changed"); + $this->redirect_to_user($duser); + } + } + } + if ($event->page_matches("user_admin/change_email", method: "POST")) { + $input = validate_input([ + 'id' => 'user_id,exists', + 'address' => 'email', + ]); + $duser = User::by_id($input['id']); + if ($this->user_can_edit_user($user, $duser)) { + $duser->set_email($input['address']); + $page->flash("Email changed"); + $this->redirect_to_user($duser); + } + } + if ($event->page_matches("user_admin/change_class", method: "POST")) { + $input = validate_input([ + 'id' => 'user_id,exists', + 'class' => 'user_class', + ]); + $duser = User::by_id($input['id']); + // hard-coded that only admins can change people's classes + if ($user->class->name == "admin") { + $duser->set_class($input['class']); + $page->flash("Class changed"); + $this->redirect_to_user($duser); + } + } + if ($event->page_matches("user_admin/delete_user", method: "POST", permission: Permissions::DELETE_USER)) { + $this->delete_user( + $page, + int_escape($event->req_POST('id')), + $event->get_POST("with_images") == "on", + $event->get_POST("with_comments") == "on" + ); + } if ($event->page_matches("user")) { $display_user = ($event->count_args() == 0) ? $user : User::by_name($event->get_arg(0)); @@ -267,7 +329,7 @@ class UserPage extends Extension $this->theme->display_error( 404, "No Such User", - "If you typed the ID by hand, try again; if you came from a link on this ". + "If you typed the ID by hand, try again; if you came from a link on this " . "site, it might be bug report time..." ); } @@ -294,13 +356,14 @@ class UserPage extends Extension $av = $event->display_user->get_avatar_html(); if ($av) { $event->add_stats($av, 0); - } elseif (( - $config->get_string("avatar_host") == "gravatar" - ) && + } elseif ( + ( + $config->get_string("avatar_host") == "gravatar" + ) && ($user->id == $event->display_user->id) ) { $event->add_stats( - "No avatar? This gallery uses Gravatar for avatar hosting, use the". + "No avatar? This gallery uses Gravatar for avatar hosting, use the" . "
same email address here and there to have your avatar synced
", 0 ); @@ -459,8 +522,8 @@ class UserPage extends Extension } if (!preg_match('/^[a-zA-Z0-9-_]+$/', $name)) { throw new UserCreationException( - "Username contains invalid characters. Allowed characters are ". - "letters, numbers, dash, and underscore" + "Username contains invalid characters. Allowed characters are " . + "letters, numbers, dash, and underscore" ); } if (User::by_name($name)) { @@ -472,7 +535,7 @@ class UserPage extends Extension if ($event->password != $event->password2) { throw new UserCreationException("Passwords don't match"); } - if( + if ( // Users who can create other users (ie, admins) are exempt // from the email requirement !$user->can(Permissions::CREATE_OTHER_USER) && @@ -496,8 +559,10 @@ class UserPage extends Extension public static function has_user_query(array $context): bool { foreach ($context as $term) { - if (preg_match(self::USER_SEARCH_REGEX, $term) || - preg_match(self::USER_ID_SEARCH_REGEX, $term)) { + if ( + preg_match(self::USER_SEARCH_REGEX, $term) || + preg_match(self::USER_ID_SEARCH_REGEX, $term) + ) { return true; } } @@ -517,7 +582,7 @@ class UserPage extends Extension $duser = User::by_name($matches[2]); if (is_null($duser)) { throw new SearchTermParseException( - "Can't find the user named ".html_escape($matches[2]) + "Can't find the user named " . html_escape($matches[2]) ); } $event->add_querylet(new Querylet("images.owner_id {$matches[1]}= {$duser->id}")); @@ -535,7 +600,7 @@ class UserPage extends Extension if ($event->key === HelpPages::SEARCH) { $block = new Block(); $block->header = "Users"; - $block->body = (string)$this->theme->get_help_html(); + $block->body = (string) $this->theme->get_help_html(); $event->add_block($block); } } @@ -606,38 +671,6 @@ class UserPage extends Extension } } - private function page_create(PageRequestEvent $event): void - { - 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); - return; - } - - if ($event->method == "GET") { - $this->theme->display_signup_page($page); - } else { - try { - $uce = send_event(new UserCreationEvent( - $event->req_POST('name'), - $event->req_POST('pass1'), - $event->req_POST('pass2'), - $event->req_POST('email'), - true - )); - $this->set_login_cookie($uce->username); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("user")); - } catch (UserCreationException $ex) { - $this->theme->display_error(400, "User Creation Error", $ex->getMessage()); - } - } - } - private function create_user(UserCreationEvent $event): User { global $database; @@ -666,7 +699,7 @@ class UserPage extends Extension global $config; $addr = get_session_ip($config); $hash = User::by_name($name)->passhash; - return md5($hash.$addr); + return md5($hash . $addr); } private function set_login_cookie(string $name): void @@ -720,64 +753,6 @@ class UserPage extends Extension } } - private function change_name_wrapper(User $duser, string $name): void - { - global $page, $user; - - if ($user->can(Permissions::EDIT_USER_NAME) && $this->user_can_edit_user($user, $duser)) { - $duser->set_name($name); - $page->flash("Username changed"); - // TODO: set login cookie if user changed themselves - $this->redirect_to_user($duser); - } else { - $this->theme->display_error(400, "Error", "Permission denied"); - } - } - - private function change_password_wrapper(User $duser, string $pass1, string $pass2): void - { - global $page, $user; - - if ($this->user_can_edit_user($user, $duser)) { - if ($pass1 != $pass2) { - $this->theme->display_error(400, "Error", "Passwords don't match"); - } else { - // FIXME: send_event() - $duser->set_password($pass1); - - if ($duser->id == $user->id) { - $this->set_login_cookie($duser->name); - } - - $page->flash("Password changed"); - $this->redirect_to_user($duser); - } - } - } - - private function change_email_wrapper(User $duser, string $address): void - { - global $page, $user; - - if ($this->user_can_edit_user($user, $duser)) { - $duser->set_email($address); - - $page->flash("Email changed"); - $this->redirect_to_user($duser); - } - } - - private function change_class_wrapper(User $duser, string $class): void - { - global $page, $user; - - if ($user->class->name == "admin") { - $duser->set_class($class); - $page->flash("Class changed"); - $this->redirect_to_user($duser); - } - } - /** * @return array */ @@ -837,47 +812,43 @@ class UserPage extends Extension $page->set_heading("Error"); $page->add_block(new NavBlock()); - if (!$user->can(Permissions::DELETE_USER)) { - $page->add_block(new Block("Not Admin", "Only admins can delete accounts")); - } else { - $duser = User::by_id($uid); - log_warning("user", "Deleting user #{$uid} (@{$duser->name})"); + $duser = User::by_id($uid); + log_warning("user", "Deleting user #{$uid} (@{$duser->name})"); - if ($with_images) { - log_warning("user", "Deleting user #{$uid} (@{$duser->name})'s uploads"); - $image_ids = $database->get_col("SELECT id FROM images WHERE owner_id = :owner_id", ["owner_id" => $uid]); - foreach ($image_ids as $image_id) { - $image = Image::by_id((int)$image_id); - if ($image) { - send_event(new ImageDeletionEvent($image)); - } + if ($with_images) { + log_warning("user", "Deleting user #{$uid} (@{$duser->name})'s uploads"); + $image_ids = $database->get_col("SELECT id FROM images WHERE owner_id = :owner_id", ["owner_id" => $uid]); + foreach ($image_ids as $image_id) { + $image = Image::by_id((int) $image_id); + if ($image) { + send_event(new ImageDeletionEvent($image)); } - } else { - $database->execute( - "UPDATE images SET owner_id = :new_owner_id WHERE owner_id = :old_owner_id", - ["new_owner_id" => $config->get_int('anon_id'), "old_owner_id" => $uid] - ); } - - if ($with_comments) { - log_warning("user", "Deleting user #{$uid} (@{$duser->name})'s comments"); - $database->execute("DELETE FROM comments WHERE owner_id = :owner_id", ["owner_id" => $uid]); - } else { - $database->execute( - "UPDATE comments SET owner_id = :new_owner_id WHERE owner_id = :old_owner_id", - ["new_owner_id" => $config->get_int('anon_id'), "old_owner_id" => $uid] - ); - } - - send_event(new UserDeletionEvent($uid)); - + } else { $database->execute( - "DELETE FROM users WHERE id = :id", - ["id" => $uid] + "UPDATE images SET owner_id = :new_owner_id WHERE owner_id = :old_owner_id", + ["new_owner_id" => $config->get_int('anon_id'), "old_owner_id" => $uid] ); - - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link()); } + + if ($with_comments) { + log_warning("user", "Deleting user #{$uid} (@{$duser->name})'s comments"); + $database->execute("DELETE FROM comments WHERE owner_id = :owner_id", ["owner_id" => $uid]); + } else { + $database->execute( + "UPDATE comments SET owner_id = :new_owner_id WHERE owner_id = :old_owner_id", + ["new_owner_id" => $config->get_int('anon_id'), "old_owner_id" => $uid] + ); + } + + send_event(new UserDeletionEvent($uid)); + + $database->execute( + "DELETE FROM users WHERE id = :id", + ["id" => $uid] + ); + + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link()); } } diff --git a/ext/user/test.php b/ext/user/test.php index 2aa53d8e..495a84e8 100644 --- a/ext/user/test.php +++ b/ext/user/test.php @@ -58,7 +58,7 @@ class UserPageTest extends ShimmiePHPUnitTestCase { global $page; - $this->assertException(UserCreationException::class, function () { + $this->assertException(PermissionDeniedException::class, function () { $this->log_out(); $this->post_page('user_admin/create_other', [ 'name' => 'testnew', diff --git a/ext/user_config/main.php b/ext/user_config/main.php index 06e2df20..49fd418d 100644 --- a/ext/user_config/main.php +++ b/ext/user_config/main.php @@ -125,47 +125,34 @@ class UserConfig extends Extension } } - if ($event->page_matches("user_admin")) { - if (!$user->check_auth_token()) { - return; - } - switch ($event->get_arg(0)) { - case "reset_api_key": - $user_config->set_string(self::API_KEY, ""); + if ($event->page_matches("user_admin/reset_api_key", method: "POST")) { + $user_config->set_string(self::API_KEY, ""); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("user")); - - break; - } + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("user")); } } - if ($event->page_matches("user_config")) { - if (!$user->can(Permissions::CHANGE_USER_SETTING)) { - $this->theme->display_permission_denied(); - } else { - if ($event->count_args() == 0) { - $uobe = send_event(new UserOptionsBuildingEvent($user, new SetupPanel($user_config))); - $this->theme->display_user_config_page($page, $uobe->user, $uobe->panel); - } elseif ($event->get_arg(0) == "save" && $user->check_auth_token()) { - $input = validate_input([ - 'id' => 'user_id,exists' - ]); - $duser = User::by_id($input['id']); + if ($event->page_matches("user_config", permission: Permissions::CHANGE_USER_SETTING)) { + if ($event->count_args() == 0) { + $uobe = send_event(new UserOptionsBuildingEvent($user, new SetupPanel($user_config))); + $this->theme->display_user_config_page($page, $uobe->user, $uobe->panel); + } elseif ($event->get_arg(0) == "save" && $user->check_auth_token()) { + $input = validate_input([ + 'id' => 'user_id,exists' + ]); + $duser = User::by_id($input['id']); - if ($user->id != $duser->id && !$user->can(Permissions::CHANGE_OTHER_USER_SETTING)) { - $this->theme->display_permission_denied(); - return; - } - - $target_config = UserConfig::get_for_user($duser->id); - send_event(new ConfigSaveEvent($target_config, $event->POST)); - $target_config->save(); - $page->flash("Config saved"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("user_config")); + if ($user->id != $duser->id && !$user->can(Permissions::CHANGE_OTHER_USER_SETTING)) { + throw new PermissionDeniedException("You do not have permission to change other user's settings"); } + + $target_config = UserConfig::get_for_user($duser->id); + send_event(new ConfigSaveEvent($target_config, $event->POST)); + $target_config->save(); + $page->flash("Config saved"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("user_config")); } } } diff --git a/ext/user_config/test.php b/ext/user_config/test.php index 29d984e3..c994fddd 100644 --- a/ext/user_config/test.php +++ b/ext/user_config/test.php @@ -10,9 +10,9 @@ class UserConfigTest extends ShimmiePHPUnitTestCase public function testUserConfigPage(): void { - $this->get_page('user_config'); - $this->assert_title("Permission Denied"); - $this->assert_no_text(self::OPTIONS_BLOCK_TITLE); + $this->assertException(PermissionDeniedException::class, function () { + $this->get_page('user_config'); + }); $this->log_in_as_user(); $this->get_page('user_config'); diff --git a/ext/view/main.php b/ext/view/main.php index e76152ff..57546eed 100644 --- a/ext/view/main.php +++ b/ext/view/main.php @@ -72,7 +72,7 @@ class ViewPost extends Extension } else { $this->theme->display_error(404, "Post not found", "No post in the database has the ID #$image_id"); } - } elseif ($event->page_matches("post/set")) { + } elseif ($event->page_matches("post/set", method: "POST")) { $image_id = int_escape($event->req_POST('image_id')); $image = Image::by_id($image_id); if (!$image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK)) { diff --git a/ext/wiki/main.php b/ext/wiki/main.php index c7d9e849..96da0a08 100644 --- a/ext/wiki/main.php +++ b/ext/wiki/main.php @@ -197,7 +197,7 @@ class Wiki extends Extension if ($this->can_edit($user, $content)) { $this->theme->display_page_editor($page, $content); } else { - $this->theme->display_permission_denied(); + throw new PermissionDeniedException("You are not allowed to edit this page"); } } elseif($action == "save" && $user->check_auth_token()) { $rev = int_escape($event->req_POST('revision')); @@ -214,7 +214,7 @@ class Wiki extends Extension $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("wiki/$u_title")); } else { - $this->theme->display_permission_denied(); + throw new PermissionDeniedException("You are not allowed to edit this page"); } } elseif($action == "delete_revision" && $user->check_auth_token()) { $content = $this->get_page($title); @@ -225,7 +225,7 @@ class Wiki extends Extension $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("wiki/$u_title")); } else { - $this->theme->display_permission_denied(); + throw new PermissionDeniedException("You are not allowed to edit this page"); } } elseif($action == "delete_all" && $user->check_auth_token()) { if ($user->can(Permissions::WIKI_ADMIN)) { diff --git a/ext/wiki/test.php b/ext/wiki/test.php index c75dcae5..695802e1 100644 --- a/ext/wiki/test.php +++ b/ext/wiki/test.php @@ -22,8 +22,9 @@ class WikiTest extends ShimmiePHPUnitTestCase $this->assert_title("test"); $this->assert_text("This is a default page"); - $this->get_page("wiki/test/edit"); - $this->assert_no_text("Editor"); + $this->assertException(PermissionDeniedException::class, function () { + $this->get_page("wiki/test/edit"); + }); } // Admins can edit diff --git a/index.php b/index.php index 63d7ad17..02664d40 100644 --- a/index.php +++ b/index.php @@ -105,7 +105,15 @@ try { if ($database->is_transaction_open()) { $database->rollback(); } - _fatal_error($e); + if(is_a($e, \Shimmie2\UserErrorException::class)) { + $page->set_mode(PageMode::PAGE); + $page->set_code($e->http_code); + $page->set_title("Error"); + $page->add_block(new Block(null, \MicroHTML\SPAN($e->getMessage()))); + $page->display(); + } else { + _fatal_error($e); + } $exit_code = 1; } finally { $_tracer->end();