diff --git a/assign.php b/assign.php index 0e716059f..6509a488c 100644 --- a/assign.php +++ b/assign.php @@ -124,16 +124,18 @@ function pcAssignments($qreq) { } } -if (isset($Qreq->update) && $Me->allow_administer($prow) && $Qreq->post_ok()) { - pcAssignments($Qreq); -} else if (isset($Qreq->update) && $Qreq->ajax) { - json_exit(["ok" => false, "error" => "Only administrators can assign papers."]); +if (isset($Qreq->update) && $Qreq->valid_post()) { + if ($Me->allow_administer($prow)) { + pcAssignments($Qreq); + } else if ($Qreq->ajax) { + json_exit(["ok" => false, "error" => "Only administrators can assign papers."]); + } } // add review requests if ((isset($Qreq->requestreview) || isset($Qreq->approvereview)) - && $Qreq->post_ok()) { + && $Qreq->valid_post()) { $result = RequestReview_API::requestreview($Me, $Qreq, $prow); $result = JsonResult::make($result); if ($result->content["ok"]) { @@ -158,7 +160,7 @@ function pcAssignments($qreq) { // deny review request if ((isset($Qreq->deny) || isset($Qreq->denyreview)) - && $Qreq->post_ok()) { + && $Qreq->valid_post()) { $result = RequestReview_API::denyreview($Me, $Qreq, $prow); $result = JsonResult::make($result); if ($result->content["ok"]) { @@ -173,7 +175,7 @@ function pcAssignments($qreq) { // retract review request if (isset($Qreq->retractreview) - && $Qreq->post_ok()) { + && $Qreq->valid_post()) { $result = RequestReview_API::retractreview($Me, $Qreq, $prow); $result = JsonResult::make($result); if ($result->content["ok"]) { @@ -190,9 +192,9 @@ function pcAssignments($qreq) { } } -// retract review request +// remove declined review if (isset($Qreq->undeclinereview) - && $Qreq->post_ok()) { + && $Qreq->valid_post()) { $result = RequestReview_API::undeclinereview($Me, $Qreq, $prow); $result = JsonResult::make($result); if ($result->content["ok"]) { diff --git a/autoassign.php b/autoassign.php index 88dd0084d..d7fc308e9 100644 --- a/autoassign.php +++ b/autoassign.php @@ -13,7 +13,7 @@ if (!isset($Qreq->q) || trim($Qreq->q) === "(All)") { $Qreq->q = ""; } -if ($Qreq->post_ok()) { +if ($Qreq->valid_post()) { header("X-Accel-Buffering: no"); // NGINX: do not hold on to file } @@ -60,7 +60,7 @@ if ($Conf->setting("autoassign_badpairs")) { $Qreq->badpairs = 1; } -} else if ($Me->privChair && isset($Qreq->assign) && $Qreq->post_ok()) { +} else if ($Me->privChair && isset($Qreq->assign) && $Qreq->valid_post()) { $x = array(); for ($i = 1; isset($Qreq["bpa$i"]); ++$i) { if ($Qreq["bpa$i"] @@ -150,7 +150,7 @@ function sanitize_qreq_redirect($qreq) { if ($Qreq->saveassignment && $Qreq->submit && isset($Qreq->assignment) - && $Qreq->post_ok()) { + && $Qreq->valid_post()) { $assignset = new AssignmentSet($Me, true); $assignset->enable_papers($SSel->selection()); $assignset->parse($Qreq->assignment); @@ -546,7 +546,7 @@ function echo_result() { '
Bulk update
', '
'; -if (isset($Qreq->a) && isset($Qreq->pctyp) && $Qreq->post_ok()) { +if (isset($Qreq->a) && isset($Qreq->pctyp) && $Qreq->valid_post()) { if (isset($Qreq->assignment) && isset($Qreq->showassignment)) { $ai = new AutoassignerInterface($Me, $Qreq, $SSel); $ai->echo_result(); diff --git a/bulkassign.php b/bulkassign.php index 76bf789de..1089935b3 100644 --- a/bulkassign.php +++ b/bulkassign.php @@ -12,7 +12,7 @@ ]); $Qreq->rev_round = (string) $Conf->sanitize_round_name($Qreq->rev_round); -if ($Qreq->post_ok()) { +if ($Qreq->valid_post()) { header("X-Accel-Buffering: no"); // NGINX: do not hold on to file } @@ -90,7 +90,7 @@ function complete_assignment($qreq, $callback) { // perform quick assignments all at once if (isset($Qreq->saveassignment) - && $Qreq->post_ok() + && $Qreq->valid_post() && isset($Qreq->file) && $Qreq->assignment_size_estimate < 1000 && complete_assignment($Qreq, null)) { @@ -112,7 +112,7 @@ function complete_assignment($qreq, $callback) { unset($Qreq->bulkentry); } if (isset($Qreq->upload) - && $Qreq->post_ok() + && $Qreq->valid_post() && ($Qreq->bulkentry || $Qreq->has_file("bulk"))) { flush(); while (@ob_end_flush()) { @@ -175,7 +175,7 @@ function complete_assignment($qreq, $callback) { } if (isset($Qreq->saveassignment) - && $Qreq->post_ok() + && $Qreq->valid_post() && isset($Qreq->file) && $Qreq->assignment_size_estimate >= 1000) { complete_assignment($Qreq, "keep_browser_alive"); diff --git a/buzzer.php b/buzzer.php index d82f55596..2ac50a284 100644 --- a/buzzer.php +++ b/buzzer.php @@ -36,7 +36,7 @@ function kiosk_manager(Contact $user, Qrequest $qreq) { $user->conf->save_setting("__tracker_kiosk", 1, $kiosks); } // maybe sign out to kiosk - if ($qreq->signout_to_kiosk && $qreq->post_ok()) { + if ($qreq->signout_to_kiosk && $qreq->valid_post()) { $user = LoginHelper::logout($user, false); ensure_session(ENSURE_SESSION_REGENERATE_ID); $key = $kiosk_keys[$qreq->buzzer_showpapers ? 1 : 0]; diff --git a/checkupdates.php b/checkupdates.php index c695500e7..8d9e8d771 100644 --- a/checkupdates.php +++ b/checkupdates.php @@ -5,7 +5,10 @@ require_once("src/initweb.php"); header("Content-Type: " . ($Qreq->text ? "text/plain" : "application/json")); -if ($Me->privChair && $Qreq->post_ok() && isset($Qreq->ignore)) { +if ($Me->privChair + && $Qreq->valid_token() + && !$Qreq->is_head() + && isset($Qreq->ignore)) { $when = time() + 86400 * 2; $Conf->qe("insert into Settings (name, value) values (?, ?) on duplicate key update value=?", "ignoreupdate_" . $Qreq->ignore, $when, $when); } diff --git a/index.php b/index.php index 4274045d1..3b6fc2ed2 100644 --- a/index.php +++ b/index.php @@ -30,7 +30,7 @@ function gx_call_requests(Conf $conf, Contact $user, Qrequest $qreq, $group, Gro $not_allowed = true; } } - if ($not_allowed && $qreq->method() === "POST" && !$qreq->post_ok()) { + if ($not_allowed && $qreq->is_post() && !$qreq->valid_token()) { $conf->msg($conf->_i("badpost"), 2); } foreach ($reqgj as $gj) { diff --git a/lib/login.php b/lib/login.php index d6b5b6c80..2b0af266b 100644 --- a/lib/login.php +++ b/lib/login.php @@ -72,7 +72,7 @@ static private function user_lookup(Conf $conf, Qrequest $qreq) { static function login_info(Conf $conf, Qrequest $qreq) { assert(!$conf->external_login()); - assert($qreq->post_ok()); + assert($qreq->valid_post()); $user = self::user_lookup($conf, $qreq); if (is_array($user)) { @@ -213,7 +213,7 @@ static function check_postlogin(Contact $user, Qrequest $qreq) { static function new_account_info(Conf $conf, Qrequest $qreq) { assert($conf->allow_user_self_register()); - assert($qreq->post_ok()); + assert($qreq->valid_post()); $user = self::user_lookup($conf, $qreq); if (is_array($user)) { diff --git a/lib/qrequest.php b/lib/qrequest.php index 5be4cca1f..50045c345 100644 --- a/lib/qrequest.php +++ b/lib/qrequest.php @@ -43,6 +43,10 @@ function is_get() { function is_post() { return $this->____method === "POST"; } + /** @return bool */ + function is_head() { + return $this->____method === "HEAD"; + } /** @return ?string */ function page() { return $this->____page; @@ -287,13 +291,30 @@ function checked_annex($name, $class) { function set_annex($name, $x) { $this->____x[$name] = $x; } - function approve_post() { + /** @return void */ + function approve_token() { $this->____post_ok = true; } /** @return bool */ + function valid_token() { + return $this->____post_ok; + } + /** @deprecated + * @return bool */ function post_ok() { + if ($this->____post_ok && $this->____method !== "POST") { + error_log("Qrequest::post_ok() on {$this->____method}"); + } return $this->____post_ok; } + /** @return bool */ + function valid_post() { + if ($this->____post_ok && $this->____method !== "POST") { + error_log("Qrequest::valid_post() on {$this->____method}"); + } + return $this->____post_ok && $this->____method === "POST"; + } + /** @return void */ function set_post_empty() { $this->____post_empty = true; } @@ -304,12 +325,11 @@ function post_empty() { function xt_allow($e) { if ($e === "post") { - return $this->method() === "POST" && $this->post_ok(); + return $this->____method === "POST" && $this->____post_ok; } else if ($e === "anypost") { - return $this->method() === "POST"; + return $this->____method === "POST"; } else if ($e === "getpost") { - return ($this->method() === "POST" || $this->method() === "GET") - && $this->post_ok(); + return in_array($this->____method, ["POST", "GET", "HEAD"]) && $this->____post_ok; } else if (str_starts_with($e, "req.")) { foreach (explode(" ", $e) as $w) { if (str_starts_with($w, "req.") diff --git a/mail.php b/mail.php index c1b34e0ad..3f68ab2d2 100644 --- a/mail.php +++ b/mail.php @@ -582,13 +582,14 @@ private function run() { && !$Qreq->psearch && !$Qreq->again && !$recip->error - && $Qreq->post_ok()) { - if ($Qreq->send && $Qreq->mailid) + && $Qreq->valid_post()) { + if ($Qreq->send && $Qreq->mailid) { MailSender::send2($Me, $recip, $Qreq); - else if ($Qreq->send) + } else if ($Qreq->send) { MailSender::send1($Me, $recip, $Qreq); - else if ($Qreq->check || $Qreq->group || $Qreq->ungroup) + } else if ($Qreq->check || $Qreq->group || $Qreq->ungroup) { MailSender::check($Me, $recip, $Qreq); + } } diff --git a/manualassign.php b/manualassign.php index ef7a7a007..19bf32e32 100644 --- a/manualassign.php +++ b/manualassign.php @@ -104,10 +104,12 @@ function saveAssignments($qreq, $reviewer) { } -if ($Qreq->update && $reviewer && $Qreq->post_ok()) { - saveAssignments($Qreq, $reviewer); -} else if ($Qreq->update) { - Conf::msg_error("You need to select a reviewer."); +if ($Qreq->update && $Qreq->valid_post()) { + if ($reviewer) { + saveAssignments($Qreq, $reviewer); + } else { + Conf::msg_error("You need to select a reviewer."); + } } diff --git a/mergeaccounts.php b/mergeaccounts.php index fc8bc0743..d1738f42d 100644 --- a/mergeaccounts.php +++ b/mergeaccounts.php @@ -3,8 +3,9 @@ // Copyright (c) 2006-2020 Eddie Kohler; see LICENSE. require_once("src/initweb.php"); -if (!$Me->email) +if (!$Me->email) { $Me->escape(); +} $MergeError = ""; function crpmerge($qreq, $MiniMe) { @@ -45,7 +46,7 @@ function crpmerge($qreq, $MiniMe) { } } -if (isset($Qreq->merge) && $Qreq->post_ok()) { +if (isset($Qreq->merge) && $Qreq->valid_post()) { if (!$Qreq->email) { $MergeError = "Enter an email address to merge."; Ht::error_at("email"); diff --git a/offline.php b/offline.php index 20bcc9b9c..6a03fd945 100644 --- a/offline.php +++ b/offline.php @@ -3,8 +3,9 @@ // Copyright (c) 2006-2020 Eddie Kohler; see LICENSE. require_once("src/initweb.php"); -if (!$Me->email) +if (!$Me->email) { $Me->escape(); +} $rf = $Conf->review_form(); @@ -26,7 +27,7 @@ // upload review form action if (isset($Qreq->uploadForm) && $Qreq->has_file("uploadedFile") - && $Qreq->post_ok()) { + && $Qreq->valid_post()) { $tf = ReviewValues::make_text($rf, $Qreq->file_contents("uploadedFile"), $Qreq->file_filename("uploadedFile")); while ($tf->parse_text($Qreq->override)) @@ -68,7 +69,7 @@ function setTagIndexes(Contact $user, $qreq) { } if ((isset($Qreq->setvote) || isset($Qreq->setrank)) && $Me->is_reviewer() - && $Qreq->post_ok()) { + && $Qreq->valid_post()) { setTagIndexes($Me, $Qreq); } diff --git a/paper.php b/paper.php index 9c3fae749..77a66df34 100644 --- a/paper.php +++ b/paper.php @@ -15,7 +15,7 @@ if (isset($Qreq->p) && ctype_digit($Qreq->p) && !$Qreq->path() - && !$Qreq->post_ok()) { + && $Qreq->is_get()) { $Conf->redirect_self($Qreq); } if (!isset($Qreq->p) @@ -42,7 +42,7 @@ if ($Me->is_empty()) { $Me->escape(); } -if ($Qreq->post_ok() && !$Me->has_account_here()) { +if ($Qreq->valid_token() && !$Me->has_account_here()) { if (isset($Qreq->update) && $Me->can_start_paper()) { $Me->activate_database_account(); } else { @@ -78,6 +78,14 @@ function errorMsgExit($msg) { Conf::$main->post_missing_msg(); } +// cancel action +if ($Qreq->cancel) { + if ($prow && $prow->timeSubmitted && $Qreq->m === "edit") { + unset($Qreq->m); + } + $Conf->redirect_self($Qreq); +} + // grab paper row function loadRows() { @@ -101,7 +109,7 @@ function loadRows() { // withdraw and revive actions -if (isset($Qreq->withdraw) && $prow && $Qreq->post_ok()) { +if (isset($Qreq->withdraw) && $prow && $Qreq->valid_post()) { if (!($whyNot = $Me->perm_withdraw_paper($prow))) { $reason = (string) $Qreq->reason; if ($reason === "" @@ -142,7 +150,8 @@ function loadRows() { Conf::msg_error(whyNotText($whyNot) . " The submission has not been withdrawn."); } } -if (isset($Qreq->revive) && $prow && $Qreq->post_ok()) { + +if (isset($Qreq->revive) && $prow && $Qreq->valid_post()) { if (!($whyNot = $Me->perm_revive_paper($prow))) { $aset = new AssignmentSet($Me, true); $aset->enable_papers($prow); @@ -360,7 +369,7 @@ function update_paper(Qrequest $qreq, $action) { } -if (($Qreq->update || $Qreq->submitfinal) && $Qreq->post_ok()) { +if (($Qreq->update || $Qreq->submitfinal) && $Qreq->valid_post()) { // choose action $action = "update"; if ($Qreq->submitfinal && $prow) { @@ -387,7 +396,7 @@ function update_paper(Qrequest $qreq, $action) { && $Me->can_finalize_paper($prow)); } -if ($Qreq->updatecontacts && $Qreq->post_ok() && $prow) { +if ($Qreq->updatecontacts && $Qreq->valid_post() && $prow) { if ($Me->can_administer($prow) || $Me->act_author_view($prow)) { $ps = new PaperStatus($Conf, $Me); if ($ps->prepare_save_paper_web($Qreq, $prow, "updatecontacts")) { @@ -409,13 +418,13 @@ function update_paper(Qrequest $qreq, $action) { $useRequest = true; } -if ($Qreq->updateoverride && $Qreq->post_ok() && $prow) { +if ($Qreq->updateoverride && $Qreq->valid_post() && $prow) { $Conf->redirect_self($Qreq, ["p" => $prow->paperId, "m" => "edit", "forceShow" => 1]); } // delete action -if ($Qreq->delete && $Qreq->post_ok()) { +if ($Qreq->delete && $Qreq->valid_post()) { if (!$prow) { $Conf->confirmMsg("Submission deleted."); } else if (!$Me->can_administer($prow)) { @@ -432,12 +441,6 @@ function update_paper(Qrequest $qreq, $action) { errorMsgExit(""); } } -if ($Qreq->cancel && $Qreq->post_ok()) { - if ($prow && $prow->timeSubmitted && $Qreq->m === "edit") { - unset($Qreq->m); - } - $Conf->redirect_self($Qreq); -} // correct modes diff --git a/profile.php b/profile.php index e19422778..2da1a8137 100644 --- a/profile.php +++ b/profile.php @@ -42,7 +42,7 @@ function change_email_by_capability($Qreq) { if ($newcdbu->contactdb_disabled()) { // NB do not use is_disabled() Conf::msg_error("changeemail", "That user is globally disabled."); return false; - } else if ($Qreq->go && $Qreq->post_ok()) { + } else if ($Qreq->go && $Qreq->valid_post()) { $Qreq->password = trim((string) $Qreq->password); $info = $newcdbu->check_password_info($Qreq->password); if (!$info["ok"]) { @@ -55,7 +55,7 @@ function change_email_by_capability($Qreq) { if ($newemail && $Qreq->go - && $Qreq->post_ok()) { + && $Qreq->valid_post()) { $Acct->change_email($newemail); $capdata->delete(); $Conf->confirmMsg("Your email address has been changed."); @@ -416,7 +416,7 @@ function parseBulkFile($text, $filename) { return empty($errors); } -if (!$Qreq->post_ok()) { +if (!$Qreq->valid_post()) { // do nothing } else if ($Qreq->savebulk && $newProfile && $Qreq->has_file("bulk")) { if (($text = $Qreq->file_contents("bulk")) === false) { @@ -477,7 +477,7 @@ function parseBulkFile($text, $filename) { $Conf->redirect_hoturl("mergeaccounts"); } -if (isset($Qreq->delete) && !Dbl::has_error() && $Qreq->post_ok()) { +if (isset($Qreq->delete) && !Dbl::has_error() && $Qreq->valid_post()) { if (!$Me->privChair) { Conf::msg_error("Only administrators can delete accounts."); } else if ($Acct->contactId == $Me->contactId) { diff --git a/review.php b/review.php index 7c70daa39..c6b9fc678 100644 --- a/review.php +++ b/review.php @@ -58,7 +58,7 @@ function review_load() { // cancel action -if ($Qreq->cancel && $Qreq->post_ok()) { +if ($Qreq->cancel) { $Conf->redirect_self($Qreq); } @@ -66,7 +66,7 @@ function review_load() { // upload review form action if (isset($Qreq->uploadForm) && $Qreq->has_file("uploadedFile") - && $Qreq->post_ok()) { + && $Qreq->valid_post()) { // parse form, store reviews $tf = ReviewValues::make_text($rf, $Qreq->file_contents("uploadedFile"), $Qreq->file_filename("uploadedFile")); @@ -88,7 +88,7 @@ function review_load() { && $paperTable->editrrow && $paperTable->editrrow->reviewStatus >= ReviewInfo::RS_DELIVERED && $Me->can_administer($prow) - && $Qreq->post_ok()) { + && $Qreq->valid_post()) { $result = $Me->unsubmit_review_row($paperTable->editrrow); if (!Dbl::is_error($result) && $result->affected_rows) { $Me->log_activity_for($paperTable->editrrow->contactId, "Review {$paperTable->editrrow->reviewId} unsubmitted", $prow); @@ -104,7 +104,7 @@ function review_load() { // update review action -if (isset($Qreq->update) && $Qreq->post_ok()) { +if (isset($Qreq->update) && $Qreq->valid_post()) { $tf = new ReviewValues($rf); $tf->paperId = $prow->paperId; if (($whyNot = $Me->perm_submit_review($prow, $paperTable->editrrow))) { @@ -133,7 +133,7 @@ function review_load() { // adopt review action if (isset($Qreq->adoptreview) - && $Qreq->post_ok() + && $Qreq->valid_post() && $paperTable->editrrow && $Me->can_approve_review($prow, $paperTable->editrrow)) { $tf = new ReviewValues($rf); @@ -162,7 +162,7 @@ function review_load() { // delete review action if (isset($Qreq->deletereview) - && $Qreq->post_ok() + && $Qreq->valid_post() && $Me->can_administer($prow)) { if (!$paperTable->editrrow) { Conf::msg_error("No review to delete."); @@ -266,7 +266,8 @@ function download_one_text_review(ReviewInfo $rrow) { // retract review request if ((isset($Qreq->refuse) || isset($Qreq->decline)) - && ($Qreq->post_ok() || $Me->capability("@ra" . $prow->paperId))) { + && ($Qreq->valid_post() + || ($Me->capability("@ra" . $prow->paperId) && !$Qreq->is_head()))) { $decline_email = null; if ($paperTable->editrrow) { $Qreq->email = $decline_email = $paperTable->editrrow->email; @@ -298,7 +299,8 @@ function download_one_text_review(ReviewInfo $rrow) { } if (isset($Qreq->accept) - && ($Qreq->post_ok() || $Me->capability("@ra" . $prow->paperId))) { + && ($Qreq->valid_post() + || ($Me->capability("@ra" . $prow->paperId) && !$Qreq->is_head()))) { $rrow = $paperTable->editrrow; if (!$rrow || (!$Me->is_my_review($rrow) && !$Me->can_administer($prow))) { diff --git a/reviewprefs.php b/reviewprefs.php index 9517693a7..2e06603e4 100644 --- a/reviewprefs.php +++ b/reviewprefs.php @@ -44,6 +44,12 @@ } +// cancel action +if ($Qreq->cancel) { + $Conf->redirect_self($Qreq); +} + + // backwards compat if ($Qreq->fn && strpos($Qreq->fn, "/") === false @@ -102,7 +108,7 @@ function savePreferences($Qreq, $reset_p) { Conf::msg_error(join("
", $aset->messages_html())); } } -if ($Qreq->fn === "saveprefs" && $Qreq->post_ok()) { +if ($Qreq->fn === "saveprefs" && $Qreq->valid_post()) { savePreferences($Qreq, true); } @@ -114,7 +120,7 @@ function savePreferences($Qreq, $reset_p) { // Set multiple paper preferences -if ($Qreq->fn === "setpref" && $Qreq->post_ok()) { +if ($Qreq->fn === "setpref" && $Qreq->valid_post()) { if (!$SSel->is_empty()) { $new_qreq = new Qrequest($Qreq->method()); foreach ($SSel->selection() as $p) { @@ -197,13 +203,15 @@ function parseUploadedPreferences($text, $filename, $apply) { exit; } } -if ($Qreq->fn === "saveuploadpref" && $Qreq->post_ok() && !$Qreq->cancel) { +if ($Qreq->fn === "saveuploadpref" && $Qreq->valid_post()) { parseUploadedPreferences($Qreq->file, $Qreq->filename, true); -} else if ($Qreq->fn === "uploadpref" && $Qreq->post_ok() && $Qreq->has_file("uploadedFile")) { - parseUploadedPreferences($Qreq->file_contents("uploadedFile"), +} else if ($Qreq->fn === "uploadpref" && $Qreq->valid_post()) { + if ($Qreq->has_file("uploadedFile")) { + parseUploadedPreferences($Qreq->file_contents("uploadedFile"), $Qreq->file_filename("uploadedFile"), false); -} else if ($Qreq->fn === "uploadpref") { - Conf::msg_error("Select a preferences file to upload."); + } else { + Conf::msg_error("Select a preferences file to upload."); + } } diff --git a/search.php b/search.php index f067e579c..e36cbd44e 100644 --- a/search.php +++ b/search.php @@ -133,7 +133,7 @@ function savesearch() { } } -if (($Qreq->savesearch || $Qreq->deletesearch) && $Me->isPC && $Qreq->post_ok()) { +if (($Qreq->savesearch || $Qreq->deletesearch) && $Me->isPC && $Qreq->valid_post()) { savesearch(); } diff --git a/settings.php b/settings.php index 4cdd7ed79..1fd3843f7 100644 --- a/settings.php +++ b/settings.php @@ -7,6 +7,10 @@ $Me->escape(); } +if (isset($Qreq->cancel)) { + $Conf->redirect_self($Qreq); +} + $Sv = SettingValues::make_request($Me, $Qreq); $Sv->session_highlight(); @@ -42,7 +46,7 @@ function choose_setting_group($qreq, SettingValues $sv) { $Group = $Qreq->group = choose_setting_group($Qreq, $Sv); $_SESSION["sg"] = $Group; -if (isset($Qreq->update) && $Qreq->post_ok()) { +if (isset($Qreq->update) && $Qreq->valid_post()) { if ($Sv->execute()) { $Me->save_session("settings_highlight", $Sv->message_field_map()); if (!empty($Sv->updated_fields())) { @@ -54,9 +58,6 @@ function choose_setting_group($qreq, SettingValues $sv) { $Conf->redirect_self($Qreq); } } -if (isset($Qreq->cancel) && $Qreq->post_ok()) { - $Conf->redirect_self($Qreq); -} $Sv->crosscheck(); @@ -84,7 +85,7 @@ function choose_setting_group($qreq, SettingValues $sv) { '
', '

', $Sv->group_title($Group), '

'; -$Sv->report(isset($Qreq->update) && $Qreq->post_ok()); +$Sv->report(isset($Qreq->update) && $Qreq->valid_post()); $Sv->render_group(strtolower($Group), ["top" => true]); diff --git a/src/api/api_reviewtoken.php b/src/api/api_reviewtoken.php index 30a3e22f1..62d1090b3 100644 --- a/src/api/api_reviewtoken.php +++ b/src/api/api_reviewtoken.php @@ -6,7 +6,7 @@ class ReviewToken_API { static function run(Contact $user, Qrequest $qreq) { assert(!$user->is_empty()); $confirm = null; - if ($qreq->is_post() && $qreq->post_ok() && isset($qreq->token)) { + if ($qreq->valid_post() && isset($qreq->token)) { if (str_starts_with($qreq->token, "[")) { $ttexts = json_decode($qreq->token); } else { diff --git a/src/api/api_search.php b/src/api/api_search.php index 62d3bc616..9787f0ecb 100644 --- a/src/api/api_search.php +++ b/src/api/api_search.php @@ -61,7 +61,7 @@ static function fieldhtml(Contact $user, Qrequest $qreq, PaperInfo $prow = null) foreach ($pl->message_set()->message_texts() as $m) { $j["errors"][] = $m; } - if ($j["ok"] && $qreq->session && $qreq->post_ok()) { + if ($j["ok"] && $qreq->session && $qreq->valid_token() && !$qreq->is_head()) { Session_API::setsession($user, $qreq->session); } return $j; diff --git a/src/conference.php b/src/conference.php index 328ff85df..ccd87366d 100644 --- a/src/conference.php +++ b/src/conference.php @@ -4761,7 +4761,7 @@ private function call_api($fn, $uf, Contact $user, Qrequest $qreq, $prow) { if ($method !== "GET" && $method !== "HEAD" && $method !== "OPTIONS" - && !$qreq->post_ok() + && !$qreq->valid_token() && (!$uf || ($uf->post ?? false)) && (!$uf || !($uf->allow_xss ?? false))) { return new JsonResult(403, "Missing credentials."); diff --git a/src/contact.php b/src/contact.php index d53853bb7..1836bd368 100644 --- a/src/contact.php +++ b/src/contact.php @@ -1452,7 +1452,7 @@ function escape($qreq = null) { } $url = $this->conf->selfurl($qreq, $x, Conf::HOTURL_RAW | Conf::HOTURL_SITE_RELATIVE); $_SESSION["login_bounce"] = [$this->conf->dsn, $url, Navigation::page(), $_POST, Conf::$now + 120]; - if ($qreq->post_ok()) { + if ($qreq->valid_token()) { $this->conf->errorMsg("You must sign in to access that page. Your changes were not saved; after signing in, you may submit them again."); } else { $this->conf->errorMsg("You must sign in to access that page."); diff --git a/src/helpers.php b/src/helpers.php index 3ff850ccc..b25333fa9 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -171,7 +171,7 @@ function json_exit($json, $arg2 = null) { if (JsonResultException::$capturing) { throw new JsonResultException($json); } else { - $json->emit($Qreq && $Qreq->post_ok()); + $json->emit($Qreq && $Qreq->valid_token()); exit; } } diff --git a/src/initweb.php b/src/initweb.php index 62b6a7193..2fad5a992 100644 --- a/src/initweb.php +++ b/src/initweb.php @@ -5,37 +5,6 @@ require_once("init.php"); global $Conf, $Me, $Qreq; -// Check method: GET/HEAD/POST only, except OPTIONS is allowed for API calls -if (!($_SERVER["REQUEST_METHOD"] === "GET" - || $_SERVER["REQUEST_METHOD"] === "HEAD" - || $_SERVER["REQUEST_METHOD"] === "POST" - || (Navigation::page() === "api" - && $_SERVER["REQUEST_METHOD"] === "OPTIONS"))) { - header("HTTP/1.0 405 Method Not Allowed"); - exit; -} - -// Check for PHP suffix -if (Conf::$main->opt("phpSuffix") !== null) { - Navigation::get()->php_suffix = Conf::$main->opt("phpSuffix"); -} - -// Collect $Qreq -$Qreq = Qrequest::make_global(); - -// Check for redirect to https -if (Conf::$main->opt("redirectToHttps")) { - Navigation::redirect_http_to_https(Conf::$main->opt("allowLocalHttp")); -} - -// Mark as already expired to discourage caching, but allow the browser -// to cache for history buttons -header("Cache-Control: max-age=0,must-revalidate,private"); - -// Set up Content-Security-Policy if appropriate -Conf::$main->prepare_content_security_policy(); - -// Initialize user if required function initialize_user_redirect($nav, $uindex, $nusers) { if ($nav->page === "api") { if ($nusers === 0) { @@ -54,11 +23,45 @@ function initialize_user_redirect($nav, $uindex, $nusers) { } } -function initialize_user() { +function initialize_web() { global $Qreq; $conf = Conf::$main; $nav = Navigation::get(); + // check PHP suffix + if (($php_suffix = Conf::$main->opt("phpSuffix")) !== null) { + $nav->php_suffix = $php_suffix; + } + + // maybe redirect to https + if (Conf::$main->opt("redirectToHttps")) { + Navigation::redirect_http_to_https(Conf::$main->opt("allowLocalHttp")); + } + + // collect $Qreq + $Qreq = Qrequest::make_global(); + + // check method + if ($Qreq->method() !== "GET" + && $Qreq->method() !== "POST" + && $Qreq->method() !== "HEAD" + && ($Qreq->method() !== "OPTIONS" || $nav->page !== "api")) { + header("HTTP/1.0 405 Method Not Allowed"); + exit; + } + + // mark as already expired to discourage caching, but allow the browser + // to cache for history buttons + header("Cache-Control: max-age=0,must-revalidate,private"); + + // set up Content-Security-Policy if appropriate + Conf::$main->prepare_content_security_policy(); + + // skip user initialization if requested + if (Contact::$no_guser) { + return; + } + // set up session if (($sh = $conf->opt["sessionHandler"] ?? null)) { /** @phan-suppress-next-line PhanTypeExpectedObjectOrClassName, PhanNonClassMethodCall */ @@ -73,7 +76,7 @@ function initialize_user() { $sid = $_COOKIE[$sn]; $l = strlen($Qreq->post); if ($l >= 8 && $Qreq->post === substr($sid, strlen($sid) > 16 ? 8 : 0, $l)) { - $Qreq->approve_post(); + $Qreq->approve_token(); } else if ($_SERVER["REQUEST_METHOD"] === "POST") { error_log("{$conf->dbname}: bad post={$Qreq->post}, cookie={$sid}, url=" . $_SERVER["REQUEST_URI"]); } @@ -180,6 +183,4 @@ function initialize_user() { } } -if (!Contact::$no_guser) { - initialize_user(); -} +initialize_web(); diff --git a/src/listaction.php b/src/listaction.php index fcab4b3ed..e53d54f45 100644 --- a/src/listaction.php +++ b/src/listaction.php @@ -32,7 +32,7 @@ static function grouped_extensions(Contact $user) { static private function do_call($name, Contact $user, Qrequest $qreq, $selection) { if ($qreq->method() !== "GET" && $qreq->method() !== "HEAD" - && !$qreq->post_ok()) { + && !$qreq->valid_token()) { return new JsonResult(403, "Missing credentials."); } $conf = $user->conf; diff --git a/src/meetingtracker.php b/src/meetingtracker.php index 684271910..69c204fc9 100644 --- a/src/meetingtracker.php +++ b/src/meetingtracker.php @@ -271,7 +271,7 @@ static function track_api(Contact $user, $qreq) { // or call `json_exit` on error. // track="IDENTIFIER POSITION" or track="IDENTIFIER stop" or track=stop - if (!$user->is_track_manager() || !$qreq->post_ok()) { + if (!$user->is_track_manager() || !$qreq->valid_post()) { return json_exit(403, "Permission error."); } @@ -407,7 +407,7 @@ static function track_api(Contact $user, $qreq) { } static function trackerconfig_api(Contact $user, $qreq) { - if (!$user->is_track_manager() || !$qreq->post_ok()) { + if (!$user->is_track_manager() || !$qreq->valid_post()) { return json_exit(403, "Permission error."); } diff --git a/src/partials/p_adminhome.php b/src/partials/p_adminhome.php index 05eb0f01c..6eeeea78c 100644 --- a/src/partials/p_adminhome.php +++ b/src/partials/p_adminhome.php @@ -4,14 +4,15 @@ class AdminHome_Partial { static function check_admin(Contact $user, Qrequest $qreq) { - assert($user->privChair && $qreq->post_ok()); - // NB check post_ok(), but do not check method - if (isset($qreq->clearbug)) { + assert($user->privChair && $qreq->valid_token()); + if (isset($qreq->clearbug) + && !$qreq->is_head()) { $user->conf->save_setting("bug_" . $qreq->clearbug, null); } if (isset($qreq->clearnewpcrev) && ctype_digit($qreq->clearnewpcrev) - && $user->conf->setting("pcrev_informtime", 0) <= $qreq->clearnewpcrev) { + && $user->conf->setting("pcrev_informtime", 0) <= $qreq->clearnewpcrev + && !$qreq->is_head()) { $user->conf->save_setting("pcrev_informtime", $qreq->clearnewpcrev); } if (isset($qreq->clearbug) || isset($qreq->clearnewpcrev)) { diff --git a/src/partials/p_signin.php b/src/partials/p_signin.php index e32177a2f..73bd41e63 100644 --- a/src/partials/p_signin.php +++ b/src/partials/p_signin.php @@ -40,7 +40,7 @@ static function signin_request(Contact $user, Qrequest $qreq, $gx) { Navigation::redirect(); } else if ($user->conf->opt("httpAuthLogin")) { LoginHelper::check_http_auth($user, $qreq); - } else if ($qreq->post_ok()) { + } else if ($qreq->valid_post()) { if (!$user->is_empty() && strcasecmp($qreq->email, $user->email) === 0) { Navigation::redirect(); } else if (!$qreq->start) { @@ -202,7 +202,7 @@ static function signout_request(Contact $user, Qrequest $qreq) { assert($qreq->method() === "POST"); if ($qreq->cancel) { Navigation::redirect(); - } else if ($qreq->post_ok()) { + } else if ($qreq->valid_post()) { LoginHelper::logout($user, true); Navigation::redirect($user->conf->hoturl("index", "signedout=1")); } else if (!isset($_SESSION) || $user->is_empty()) { @@ -285,7 +285,7 @@ function create_request(Contact $user, Qrequest $qreq) { Navigation::redirect(); } else if (!$user->conf->allow_user_self_register()) { // do nothing - } else if ($qreq->post_ok()) { + } else if ($qreq->valid_post()) { $info = LoginHelper::new_account_info($user->conf, $qreq); if ($info["ok"]) { $prep = self::mail_user($user->conf, $info); @@ -349,7 +349,7 @@ static function forgot_request(Contact $user, Qrequest $qreq) { assert($qreq->method() === "POST"); if ($qreq->cancel) { Navigation::redirect(); - } else if ($qreq->post_ok()) { + } else if ($qreq->valid_post()) { $info = LoginHelper::forgot_password_info($user->conf, $qreq, false); if ($info["ok"]) { self::mail_user($user->conf, $info); @@ -416,9 +416,9 @@ function reset_request(Contact $user, Qrequest $qreq) { if (preg_match('/\A\/?(U?[12][-\w]+)\/?\z/', $resetcap, $m)) { $this->_reset_cap = $m[1]; } else if (strpos($resetcap, "@") !== false) { - if ($qreq->method() === "POST" && $qreq->post_ok()) { + if ($qreq->valid_post()) { $nqreq = new Qrequest("POST", ["email" => $resetcap]); - $nqreq->approve_post(); + $nqreq->approve_token(); $nqreq->set_annex("redirect", $user->conf->hoturl("resetpassword")); self::forgot_request($user, $nqreq); // may redirect if (Ht::problem_status_at("email")) { @@ -439,8 +439,7 @@ function reset_request(Contact $user, Qrequest $qreq) { // check passwords if ($this->_reset_user - && $qreq->method() === "POST" - && $qreq->post_ok()) { + && $qreq->valid_post()) { $p1 = (string) $qreq->password; $p2 = (string) $qreq->password2; if ($p1 === "") { diff --git a/users.php b/users.php index 24d09b0fc..2b16e3cc9 100644 --- a/users.php +++ b/users.php @@ -265,7 +265,7 @@ function modify_confirm($j, $ok_message, $ok_message_optional) { } } -if ($Viewer->privChair && $Qreq->modifygo && $Qreq->post_ok() && isset($papersel)) { +if ($Viewer->privChair && $Qreq->modifygo && $Qreq->valid_post() && isset($papersel)) { if ($Qreq->modifytype == "disableaccount") { modify_confirm(UserActions::disable($Viewer, $papersel), "Accounts disabled.", true); } else if ($Qreq->modifytype == "enableaccount") { @@ -343,7 +343,7 @@ function do_tags($qreq) { } } -if ($Viewer->privChair && $Qreq->tagact && $Qreq->post_ok() && isset($papersel) +if ($Viewer->privChair && $Qreq->tagact && $Qreq->valid_post() && isset($papersel) && preg_match('/\A[ads]\z/', (string) $Qreq->tagtype)) { do_tags($Qreq); }