From 265b85d489986d805cc9f5791df1478e374202a1 Mon Sep 17 00:00:00 2001 From: Floorb <132411956+Neetpone@users.noreply.github.com> Date: Wed, 5 Jul 2023 03:22:09 -0400 Subject: [PATCH] chore: move paste actions to paste_action.php to require admin authentication --- includes/Models/AdminLog.php | 8 +++-- includes/common.php | 12 ++++--- includes/functions.php | 13 ++++++++ public/admin/common.php | 17 ++++------ public/admin/dashboard.php | 2 ++ public/admin/index.php | 20 ++++++------ public/admin/paste_action.php | 60 +++++++++++++++++++++++++++++++++++ public/paste.php | 37 --------------------- theme/bulma/view.php | 3 +- 9 files changed, 106 insertions(+), 66 deletions(-) create mode 100644 public/admin/paste_action.php diff --git a/includes/Models/AdminLog.php b/includes/Models/AdminLog.php index f50f797..750d08a 100644 --- a/includes/Models/AdminLog.php +++ b/includes/Models/AdminLog.php @@ -7,15 +7,19 @@ class AdminLog extends Model { public const ACTION_LOGIN = 0; public const ACTION_FAIL_LOGIN = 1; public const ACTION_EDIT_CONFIG = 2; + public const ACTION_HIDE_PASTE = 3; + public const ACTION_BLANK_PASTE = 4; public const ACTION_NAMES = [ 'Login', 'Failed Login', - 'Edit Config' + 'Edit Config', + 'Hide Paste', + 'Blank Paste' ]; protected $table = 'admin_logs'; - protected $fillable = ['user_id', 'action', 'ip', 'time']; + protected $fillable = ['user_id', 'action', 'ip', 'time', 'message']; public $timestamps = false; diff --git a/includes/common.php b/includes/common.php index 2e16c0f..e738d98 100644 --- a/includes/common.php +++ b/includes/common.php @@ -33,12 +33,16 @@ function urlForPage($page = '') : string { return (isset($_SERVER['HTTPS']) ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/\\') . '/' . $page; } -function urlForPaste(Paste $paste) : string { - if (PP_MOD_REWRITE) { - return "/{$paste->id}"; +function urlForPaste(int | Paste $paste) : string { + if (!is_int($paste)) { + $paste = $paste->id; } - return "/paste.php?id={$paste->id}"; + if (PP_MOD_REWRITE) { + return "/{$paste}"; + } + + return "/paste.php?id={$paste}"; } function urlForReport(Paste $paste) : string { diff --git a/includes/functions.php b/includes/functions.php index c698bab..4fc8fe6 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -1,6 +1,8 @@ $admin->id, + 'action' => $action, + 'ip' => $_SERVER['REMOTE_ADDR'], + 'message' => $message + ]); + + $log->save(); } \ No newline at end of file diff --git a/public/admin/common.php b/public/admin/common.php index 94f0dfe..9762837 100644 --- a/public/admin/common.php +++ b/public/admin/common.php @@ -5,25 +5,20 @@ if (!defined('IN_PONEPASTE')) { require_once('../../includes/common.php'); -use PonePaste\Models\AdminLog; use PonePaste\Models\User; -function updateAdminHistory(User $admin, int $action) : void { - $log = new AdminLog([ - 'user_id' => $admin->id, - 'action' => $action, - 'ip' => $_SERVER['REMOTE_ADDR'] - ]); - - $log->save(); -} - if ($current_user === null || $current_user->role < User::ROLE_MODERATOR) { header('Location: ..'); die(); } if (!isset($_SESSION['admin_login'])) { + // this is a hack, paste_id is set when POSTing to admin/paste_action.php, which we can only arrive at from a paste page + if (isset($_POST['paste_id'])) { + flashError('You must authenticate to perform that action.'); + $_SESSION['redirect_back'] = urlForPaste($_POST['paste_id']); + } + header('Location: .'); exit(); } diff --git a/public/admin/dashboard.php b/public/admin/dashboard.php index 15a0fc4..c86e2b5 100644 --- a/public/admin/dashboard.php +++ b/public/admin/dashboard.php @@ -231,6 +231,7 @@ $is_admin = $current_user->role >= User::ROLE_ADMIN; Username Date Action + Information IP Address @@ -240,6 +241,7 @@ $is_admin = $current_user->role >= User::ROLE_ADMIN; user->username); ?> time); ?> action]); ?> + message) ? pp_html_escape($entry->message) : '[none]' ?> ip) : '[masked]' ?> diff --git a/public/admin/index.php b/public/admin/index.php index 6ffa202..06ec3a8 100644 --- a/public/admin/index.php +++ b/public/admin/index.php @@ -5,16 +5,6 @@ require_once(__DIR__ . '/../../includes/common.php'); use PonePaste\Models\User; use PonePaste\Models\AdminLog; -function updateAdminHistory(User $admin, int $action) : void { - $log = new AdminLog([ - 'user_id' => $admin->id, - 'action' => $action, - 'ip' => $_SERVER['REMOTE_ADDR'] - ]); - - $log->save(); -} - if ($current_user === null || $current_user->role < User::ROLE_MODERATOR) { header('Location: ..'); die(); @@ -25,11 +15,18 @@ if (isset($_SESSION['admin_login']) && $_SESSION['admin_login']) { exit(); } +$flashes = getFlashes(); + if ($_SERVER['REQUEST_METHOD'] == 'POST') { if (pp_password_verify($_POST['password'], $current_user->admin_password_hash)) { updateAdminHistory($current_user, AdminLog::ACTION_LOGIN); $_SESSION['admin_login'] = true; - header("Location: dashboard.php"); + if (isset($_SESSION['redirect_back'])) { + flashSuccess('You have been logged in. Please try your action again.'); + header('Location: ' . $_SESSION['redirect_back']); + } else { + header("Location: dashboard.php"); + } exit(); } else { updateAdminHistory($current_user, AdminLog::ACTION_FAIL_LOGIN); @@ -60,6 +57,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') { echo $msg; } ?> +

PonePaste Admin Authentication

diff --git a/public/admin/paste_action.php b/public/admin/paste_action.php new file mode 100644 index 0000000..ab44a37 --- /dev/null +++ b/public/admin/paste_action.php @@ -0,0 +1,60 @@ +is_hidden; + + if ($is_hidden) { + $paste->reports()->update(['open' => false]); + } + + $paste->is_hidden = $is_hidden; + $paste->save(); + $redis->del('ajax_pastes'); /* Expire from Redis so it doesn't show up anymore */ + + updateAdminHistory($current_user, AdminLog::ACTION_HIDE_PASTE, 'Paste ' . $paste->id . ' ' . ($is_hidden ? 'hidden' : 'unhidden') . '.'); + flashSuccess('Paste ' . ($is_hidden ? 'hidden' : 'unhidden') . '.'); + } + + header('Location: ' . urlForPaste($paste)); + die(); +} elseif (isset($_POST['blank'])) { + if (!can('blank', $paste)) { + flashError('You do not have permission to blank this paste.'); + } else { + $paste->content = ''; + $paste->title = 'Removed by moderator'; + $paste->tags()->detach(); + + $paste->save(); + $redis->del('ajax_pastes'); /* Expire from Redis so it doesn't show up anymore */ + updateAdminHistory($current_user, AdminLog::ACTION_BLANK_PASTE, 'Paste ' . $paste->id . 'blanked.'); + + flashSuccess('Paste contents blanked.'); + } + + header('Location: ' . urlForPaste($paste)); + die(); +} else { + flashError('Internal Error: No action specified.'); + header('Location: ' . urlForPaste($paste)); +} diff --git a/public/paste.php b/public/paste.php index 017198e..ecbaeed 100644 --- a/public/paste.php +++ b/public/paste.php @@ -102,43 +102,6 @@ if (isset($_POST['delete'])) { die(); } -if (isset($_POST['hide'])) { - if (!can('hide', $paste)) { - $error = 'You do not have permission to hide this paste.'; - goto Not_Valid_Paste; - } - - $is_hidden = !$paste->is_hidden; - - if ($is_hidden) { - $paste->reports()->update(['open' => false]); - } - - $paste->is_hidden = $is_hidden; - $paste->save(); - $redis->del('ajax_pastes'); /* Expire from Redis so it doesn't show up anymore */ - flashSuccess('Paste ' . ($is_hidden ? 'hidden' : 'unhidden') . '.'); - header('Location: ' . urlForPaste($paste)); - die(); -} - -if (isset($_POST['blank'])) { - if (!can('blank', $paste)) { - $error = 'You do not have permission to blank this paste.'; - goto Not_Valid_Paste; - } - - $paste->content = ''; - $paste->title = 'Removed by moderator'; - $paste->tags()->detach(); - - $paste->save(); - $redis->del('ajax_pastes'); /* Expire from Redis so it doesn't show up anymore */ - flashSuccess('Paste contents blanked.'); - header('Location: ' . urlForPaste($paste)); - die(); -} - /* Verify paste password */ $password_required = $p_password !== null && $p_password !== 'NONE'; $password_valid = true; diff --git a/theme/bulma/view.php b/theme/bulma/view.php index e631604..28ee3fc 100644 --- a/theme/bulma/view.php +++ b/theme/bulma/view.php @@ -149,7 +149,8 @@

Moderation Tools

- + +