From 7a232d6024213886ff94447439723bf027da9585 Mon Sep 17 00:00:00 2001 From: discomrade <83621080+discomrade@users.noreply.github.com> Date: Sat, 27 Apr 2024 03:04:10 +0000 Subject: [PATCH 1/2] [captcha] generalise captcha code, make signup captcha optional, turn captchas on by default --- core/captcha.php | 44 +++++++++++++++++---------------- ext/comment/main.php | 13 +++++----- ext/comment/theme.php | 2 +- ext/user/main.php | 4 ++- ext/user/theme.php | 4 ++- themes/danbooru/user.theme.php | 4 +-- themes/danbooru2/user.theme.php | 4 +-- 7 files changed, 41 insertions(+), 34 deletions(-) diff --git a/core/captcha.php b/core/captcha.php index 22c36f973..8c2a9c010 100644 --- a/core/captcha.php +++ b/core/captcha.php @@ -10,7 +10,7 @@ use ReCaptcha\ReCaptcha; -function captcha_get_html(): string +function captcha_get_html(bool $anon_only): string { global $config, $user; @@ -19,7 +19,7 @@ function captcha_get_html(): string } $captcha = ""; - if ($user->is_anonymous() && $config->get_bool("comment_captcha")) { + if (!$anon_only || $user->is_anonymous()) { $r_publickey = $config->get_string("api_recaptcha_pubkey"); if (!empty($r_publickey)) { $captcha = " @@ -33,7 +33,7 @@ function captcha_get_html(): string return $captcha; } -function captcha_check(): bool +function captcha_check(bool $anon_only): bool { global $config, $user; @@ -41,25 +41,27 @@ function captcha_check(): bool return true; } - if ($user->is_anonymous() && $config->get_bool("comment_captcha")) { - $r_privatekey = $config->get_string('api_recaptcha_privkey'); - if (!empty($r_privatekey)) { - $recaptcha = new ReCaptcha($r_privatekey); - $resp = $recaptcha->verify($_POST['g-recaptcha-response'] ?? "", get_real_ip()); - - if (!$resp->isSuccess()) { - log_info("core", "Captcha failed (ReCaptcha): " . implode("", $resp->getErrorCodes())); - return false; - } - } /*else { - session_start(); - $securimg = new \Securimage(); - if ($securimg->check($_POST['captcha_code']) === false) { - log_info("core", "Captcha failed (Securimage)"); - return false; - } - }*/ + if ($anon_only && !$user->is_anonymous()) { + return true; } + $r_privatekey = $config->get_string('api_recaptcha_privkey'); + if (!empty($r_privatekey)) { + $recaptcha = new ReCaptcha($r_privatekey); + $resp = $recaptcha->verify($_POST['g-recaptcha-response'] ?? "", get_real_ip()); + + if (!$resp->isSuccess()) { + log_info("core", "Captcha failed (ReCaptcha): " . implode("", $resp->getErrorCodes())); + return false; + } + } /*else { + session_start(); + $securimg = new \Securimage(); + if ($securimg->check($_POST['captcha_code']) === false) { + log_info("core", "Captcha failed (Securimage)"); + return false; + } + }*/ + return true; } diff --git a/ext/comment/main.php b/ext/comment/main.php index ddb77b662..75583bfea 100644 --- a/ext/comment/main.php +++ b/ext/comment/main.php @@ -129,7 +129,7 @@ public function onInitExt(InitExtEvent $event): void $config->set_default_int('comment_limit', 10); $config->set_default_int('comment_list_count', 10); $config->set_default_int('comment_count', 5); - $config->set_default_bool('comment_captcha', false); + $config->set_default_bool('comment_captcha', true); } public function onDatabaseUpgrade(DatabaseUpgradeEvent $event): void @@ -358,8 +358,8 @@ public function onCommentDeletion(CommentDeletionEvent $event): void public function onSetupBuilding(SetupBuildingEvent $event): void { $sb = $event->panel->create_new_block("Comment Options"); - $sb->add_bool_option("comment_captcha", "Require CAPTCHA for anonymous comments: "); - $sb->add_label("
Limit to "); + $sb->start_table(); + $sb->add_label("Limit to "); $sb->add_int_option("comment_limit"); $sb->add_label(" comments per "); $sb->add_int_option("comment_window"); @@ -370,8 +370,9 @@ public function onSetupBuilding(SetupBuildingEvent $event): void $sb->add_label("
Show "); $sb->add_int_option("comment_list_count"); $sb->add_label(" comments per image on the list"); - $sb->add_label("
Make samefags public "); - $sb->add_bool_option("comment_samefags_public"); + $sb->add_bool_option("comment_samefags_public", "Make samefags public", true); + $sb->add_bool_option("comment_captcha", "Require CAPTCHA for anonymous comments", true); + $sb->end_table(); } public function onSearchTermParse(SearchTermParseEvent $event): void @@ -615,7 +616,7 @@ private function comment_checks(int $image_id, User $user, string $comment): voi } // rate-limited external service checks last - elseif ($config->get_bool('comment_captcha') && !captcha_check()) { + elseif ($config->get_bool('comment_captcha') && !captcha_check(true)) { throw new CommentPostingException("Error in captcha"); } elseif ($user->is_anonymous() && $this->is_spam_akismet($comment)) { throw new CommentPostingException("Akismet thinks that your comment is spam. Try rewriting the comment, or logging in."); diff --git a/ext/comment/theme.php b/ext/comment/theme.php index adf398484..423472636 100644 --- a/ext/comment/theme.php +++ b/ext/comment/theme.php @@ -287,7 +287,7 @@ protected function build_postbox(int $image_id): string global $config; $hash = CommentList::get_hash(); - $h_captcha = $config->get_bool("comment_captcha") ? captcha_get_html() : ""; + $h_captcha = $config->get_bool("comment_captcha") ? captcha_get_html(true) : ""; return '
diff --git a/ext/user/main.php b/ext/user/main.php index 8bec2cf16..e0380d9f3 100644 --- a/ext/user/main.php +++ b/ext/user/main.php @@ -145,6 +145,7 @@ public function onInitExt(InitExtEvent $event): void $config->set_default_string("avatar_gravatar_rating", "g"); $config->set_default_bool("login_tac_bbcode", true); $config->set_default_bool("user_email_required", false); + $config->set_default_bool('signup_captcha', true); } public function onUserLogin(UserLoginEvent $event): void @@ -419,6 +420,7 @@ public function onSetupBuilding(SetupBuildingEvent $event): void $sb->add_bool_option(UserConfig::ENABLE_API_KEYS, "Enable user API keys", true); $sb->add_bool_option("login_signup_enabled", "Allow new signups", true); $sb->add_bool_option("user_email_required", "Require email address", true); + $sb->add_bool_option("signup_captcha", "Require CAPTCHA for signup", true); $sb->add_longtext_option("login_tac", "Terms & Conditions", true); $sb->add_choice_option( "user_loginshowprofile", @@ -520,7 +522,7 @@ public function onUserCreation(UserCreationEvent $event): void if (User::by_name($name)) { throw new UserCreationException("That username is already taken"); } - if (!captcha_check()) { + if ($config->get_bool("signup_captcha") && !captcha_check(true)) { throw new UserCreationException("Error in captcha"); } if ($event->password != $event->password2) { diff --git a/ext/user/theme.php b/ext/user/theme.php index 4b75004d1..d88dfbeb9 100644 --- a/ext/user/theme.php +++ b/ext/user/theme.php @@ -73,6 +73,8 @@ public function display_signup_page(Page $page): void !$user->can(Permissions::CREATE_OTHER_USER) ); + $h_captcha = $config->get_bool("signup_captcha") ? captcha_get_html(false) : ""; + $form = SHM_SIMPLE_FORM( "user_admin/create", TABLE( @@ -95,7 +97,7 @@ public function display_signup_page(Page $page): void TD(INPUT(["type" => 'email', "name" => 'email', "required" => $email_required])) ), TR( - TD(["colspan" => "2"], rawHTML(captcha_get_html())) + TD(["colspan" => "2"], rawHTML($h_captcha)) ), ), TFOOT( diff --git a/themes/danbooru/user.theme.php b/themes/danbooru/user.theme.php index 3772db162..214600be1 100644 --- a/themes/danbooru/user.theme.php +++ b/themes/danbooru/user.theme.php @@ -70,7 +70,7 @@ public function display_signup_page(Page $page): void $tac = send_event(new TextFormattingEvent($tac))->formatted; - $reca = "".captcha_get_html().""; + $h_captcha = $config->get_bool("signup_captcha") ? "".captcha_get_html(false)."" : ""; if (empty($tac)) { $html = ""; @@ -85,7 +85,7 @@ public function display_signup_page(Page $page): void Password Repeat Password Email (Optional) - $reca; + $h_captcha diff --git a/themes/danbooru2/user.theme.php b/themes/danbooru2/user.theme.php index 3772db162..214600be1 100644 --- a/themes/danbooru2/user.theme.php +++ b/themes/danbooru2/user.theme.php @@ -70,7 +70,7 @@ public function display_signup_page(Page $page): void $tac = send_event(new TextFormattingEvent($tac))->formatted; - $reca = "".captcha_get_html().""; + $h_captcha = $config->get_bool("signup_captcha") ? "".captcha_get_html(false)."" : ""; if (empty($tac)) { $html = ""; @@ -85,7 +85,7 @@ public function display_signup_page(Page $page): void Password Repeat Password Email (Optional) - $reca; + $h_captcha From 8bcbbd3c692cfc08a68024f12d670ca57460d4be Mon Sep 17 00:00:00 2001 From: discomrade <83621080+discomrade@users.noreply.github.com> Date: Sat, 27 Apr 2024 04:46:34 +0000 Subject: [PATCH 2/2] [upload] add captcha to upload form --- ext/upload/config.php | 1 + ext/upload/main.php | 13 ++++++++++++- ext/upload/theme.php | 4 ++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ext/upload/config.php b/ext/upload/config.php index 313b05368..76252d7e2 100644 --- a/ext/upload/config.php +++ b/ext/upload/config.php @@ -13,4 +13,5 @@ class UploadConfig public const TRANSLOAD_ENGINE = "transload_engine"; public const MIME_CHECK_ENABLED = "mime_check_enabled"; public const ALLOWED_MIME_STRINGS = "allowed_mime_strings"; + public const CAPTCHA = "upload_captcha"; } diff --git a/ext/upload/main.php b/ext/upload/main.php index a7e2219c8..167728da1 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -147,6 +147,11 @@ public function onSetupBuilding(SetupBuildingEvent $event): void $tes["fopen"] = "fopen"; $tes["WGet"] = "wget"; + $cap = []; + $cap["Disabled"] = 0; + $cap["Required for anonymous uploads"] = 1; + $cap["Required for all user uploads"] = 2; + $sb = $event->panel->create_new_block("Upload"); $sb->position = 10; // Output the limits from PHP so the user has an idea of what they can set. @@ -160,6 +165,7 @@ public function onSetupBuilding(SetupBuildingEvent $event): void $sb->start_table(); $sb->add_bool_option(UploadConfig::MIME_CHECK_ENABLED, "Enable upload MIME checks", true); $sb->add_multichoice_option(UploadConfig::ALLOWED_MIME_STRINGS, $this->get_mime_options(), "Allowed MIME uploads", true); + $sb->add_choice_option(UploadConfig::CAPTCHA, $cap, "
Require CAPTCHA: "); $sb->end_table(); } @@ -207,7 +213,7 @@ public function onDataUpload(DataUploadEvent $event): void public function onPageRequest(PageRequestEvent $event): void { - global $cache, $page, $user; + global $cache, $config, $page, $user; if ($user->can(Permissions::CREATE_IMAGE)) { if ($this->is_full) { @@ -229,6 +235,11 @@ public function onPageRequest(PageRequestEvent $event): void $this->theme->display_error(507, "Error", "Can't upload images: disk nearly full"); return; } + $cap = $config->get_int(UploadConfig::CAPTCHA); + if ($cap > 0 && !captcha_check($cap == 1)) { + $this->theme->display_error(503, "Error", "Error in captcha"); + return; + } $results = []; $files = array_filter($_FILES, function ($file) { diff --git a/ext/upload/theme.php b/ext/upload/theme.php index 0773a0986..f0694625b 100644 --- a/ext/upload/theme.php +++ b/ext/upload/theme.php @@ -54,12 +54,16 @@ public function display_page(Page $page): void $common_fields->appendChild($part); } + $cap = $config->get_int(UploadConfig::CAPTCHA); + $h_captcha = $cap > 0 ? captcha_get_html($cap == 1) : ""; + $form = SHM_FORM("upload", multipart: true, form_id: "file_upload"); $form->appendChild( TABLE( ["id" => "large_upload_form", "class" => "form"], $common_fields, $upload_list, + $h_captcha, TR( TD(["colspan" => "7"], INPUT(["id" => "uploadbutton", "type" => "submit", "value" => "Post"])) ),