From 79087c51a5cf4b3174a214f7f8f8a3dab759d5b9 Mon Sep 17 00:00:00 2001 From: Shish Date: Sat, 10 Feb 2024 23:15:08 +0000 Subject: [PATCH] [update] remove extension - unzipping new code over the top of old code is fundamentally unsafe --- ext/pools/main.php | 198 +++++++++++++++++++------------------------ ext/update/info.php | 19 ----- ext/update/main.php | 120 -------------------------- ext/update/script.js | 16 ---- ext/update/theme.php | 20 ----- 5 files changed, 88 insertions(+), 285 deletions(-) delete mode 100644 ext/update/info.php delete mode 100644 ext/update/main.php delete mode 100644 ext/update/script.js delete mode 100644 ext/update/theme.php diff --git a/ext/pools/main.php b/ext/pools/main.php index 1c8b84ca..9be5ca65 100644 --- a/ext/pools/main.php +++ b/ext/pools/main.php @@ -294,162 +294,135 @@ class Pools extends Extension if ($event->page_matches("pool/edit")) { $pool_id = int_escape($event->req_POST("pool_id")); $pool = $this->get_single_pool($pool_id); + $this->assert_permission($user, $pool); - 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)); + $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); } if ($event->page_matches("pool/order")) { $pool_id = int_escape($event->req_POST("pool_id")); $pool = $this->get_single_pool($pool_id); + $this->assert_permission($user, $pool); 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 = []; + $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( - " + 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)); + ["pid" => $pool_id, "iid" => (int) $row['image_id']] + ); + $images[] = ($image ? new Image($image) : null); } + + $this->theme->edit_order($page, $pool, $images); } 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( - " + 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] - ); - } + ["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"); } + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("pool/view/" . $pool_id)); } } if ($event->page_matches("pool/reverse")) { $pool_id = int_escape($event->req_POST("pool_id")); $pool = $this->get_single_pool($pool_id); + $this->assert_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( - " + $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"); - } + ["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)); } if ($event->page_matches("pool/import")) { $pool_id = int_escape($event->req_POST("pool_id")); $pool = $this->get_single_pool($pool_id); + $this->assert_permission($user, $pool); - 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"); - } + $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); } if ($event->page_matches("pool/add_posts")) { $pool_id = int_escape($event->req_POST("pool_id")); $pool = $this->get_single_pool($pool_id); + $this->assert_permission($user, $pool); - 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"); - } + $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)); } if ($event->page_matches("pool/remove_posts")) { $pool_id = int_escape($event->req_POST("pool_id")); $pool = $this->get_single_pool($pool_id); + $this->assert_permission($user, $pool); - 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] + $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] ); - $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"); + $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)); } if ($event->page_matches("pool/edit_description")) { $pool_id = int_escape($event->req_POST("pool_id")); $pool = $this->get_single_pool($pool_id); + $this->assert_permission($user, $pool); - 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"); - } + $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)); } if ($event->page_matches("pool/nuke")) { // Completely remove the given pool. @@ -462,7 +435,7 @@ class Pools extends Extension $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"); + throw new PermissionDeniedException("You do not have permission to access this page"); } } } @@ -646,6 +619,13 @@ class Pools extends Extension ); } + private function assert_permission(User $user, Pool $pool): void + { + if (!$this->have_permission($user, $pool)) { + throw new PermissionDeniedException("You do not have permission to access this pool"); + } + } + private function list_pools(Page $page, int $pageNumber, ?string $search): void { global $config, $database; @@ -758,9 +738,7 @@ class Pools extends Extension global $database, $user; $pool = $this->get_single_pool($event->pool_id); - if (!$this->have_permission($user, $pool)) { - return; - } + $this->assert_permission($user, $pool); $images = []; foreach ($event->posts as $post_id) { diff --git a/ext/update/info.php b/ext/update/info.php deleted file mode 100644 index 39c87302..00000000 --- a/ext/update/info.php +++ /dev/null @@ -1,19 +0,0 @@ - "dakutree@codeanimu.net"]; - public string $license = self::LICENSE_GPLV2; - public string $description = "Shimmie updater!"; - public array $dependencies = [AdminPageInfo::KEY]; - public ExtensionCategory $category = ExtensionCategory::ADMIN; -} diff --git a/ext/update/main.php b/ext/update/main.php deleted file mode 100644 index bf3c8a30..00000000 --- a/ext/update/main.php +++ /dev/null @@ -1,120 +0,0 @@ -set_default_string("update_guserrepo", "shish/shimmie2"); - $config->set_default_string("commit_hash", "unknown"); - $config->set_default_string("update_time", "01/01/1970"); - } - - public function onSetupBuilding(SetupBuildingEvent $event): void - { - $sb = $event->panel->create_new_block("Update"); - $sb->add_text_option("update_guserrepo", "User/Repo: "); - } - - public function onAdminBuilding(AdminBuildingEvent $event): void - { - global $config; - if ($config->get_string(UploadConfig::TRANSLOAD_ENGINE) !== "none") { - $this->theme->display_admin_block(); - } - } - - public function onPageRequest(PageRequestEvent $event): void - { - global $user, $page; - $sha = $event->get_GET('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? - } - 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? - } - } - - private function download_shimmie(string $commitSHA): bool - { - global $config; - - $g_userrepo = $config->get_string('update_guserrepo'); - - $url = "https://codeload.github.com/".$g_userrepo."/zip/".$commitSHA; - $filename = "./data/update_{$commitSHA}.zip"; - - log_info("update", "Attempting to download Shimmie commit: ".$commitSHA); - $headers = fetch_url($url, $filename); - if (($headers['Content-Type'] !== MimeType::ZIP) || ((int) $headers['Content-Length'] !== filesize($filename))) { - unlink("./data/update_{$commitSHA}.zip"); - log_warning("update", "Download failed: not zip / not same size as remote file."); - return false; - } - - return true; - } - - private function update_shimmie(string $commitSHA): bool - { - global $config; - - log_info("update", "Download succeeded. Attempting to update Shimmie."); - $ok = false; - - /** TODO: Backup all folders (except /data, /images, /thumbs) before attempting this? - Either that or point to https://github.com/shish/shimmie2/blob/master/README.txt -> Upgrade from 2.3.X **/ - - $zip = new \ZipArchive(); - if ($zip->open("./data/update_$commitSHA.zip") === true) { - for ($i = 1; $i < $zip->numFiles; $i++) { - $filename = false_throws($zip->getNameIndex($i)); - - if (substr($filename, -1) !== "/") { - copy("zip://".dirname(dirname(__DIR__)).'/'."./data/update_$commitSHA.zip"."#".$filename, substr($filename, 50)); - } - } - $ok = true; //TODO: Do proper checking to see if everything copied properly - } else { - log_warning("update", "Update failed to open ZIP."); - } - - $zip->close(); - unlink("./data/update_$commitSHA.zip"); - - if ($ok) { - $config->set_string("commit_hash", $commitSHA); - $config->set_string("update_time", date('d-m-Y')); - log_info("update", "Update succeeded?"); - } - - return $ok; - } -} diff --git a/ext/update/script.js b/ext/update/script.js deleted file mode 100644 index 424702d2..00000000 --- a/ext/update/script.js +++ /dev/null @@ -1,16 +0,0 @@ -/*jshint bitwise:true, curly:true, forin:false, noarg:true, noempty:true, nonew:true, undef:true, strict:false, browser:true, jquery:true */ - -document.addEventListener('DOMContentLoaded', () => { - if($('#updatecheck').length !== 0){ - $.getJSON('https://api.github.com/repos/shish/shimmie2/commits', function(data){ - var c = data[0]; - $('#updatecheck').html(''+ c.sha+'' + " ("+ c.commit.message+")"); - - var params = $.param({sha: c.sha, date: c.commit.committer.date}); - $('#updatelink').attr('href', function(i, val){ return val + "?" + params; }); - $('#updatelink').text("Update"); - }).fail(function(){ - $('#updatecheck').text("Loading failed. (Github down?)"); - }); - } -}); diff --git a/ext/update/theme.php b/ext/update/theme.php deleted file mode 100644 index 64a640cd..00000000 --- a/ext/update/theme.php +++ /dev/null @@ -1,20 +0,0 @@ -Current Commit: ".$config->get_string('commit_hash')." | (".$config->get_string('update_time').")". - "
Latest Commit: Loading...". - "
"; - //TODO: Show warning before use. - $page->add_block(new Block("Software Update", $html, "main", 75)); - } -}