From 4b30804121d4ad693ed08f4216a88f7c68858bfc Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Mon, 22 Aug 2022 21:07:06 +0800 Subject: [PATCH] staff message add permission --- app/Models/StaffMessage.php | 5 +- app/Repositories/MessageRepository.php | 51 ++++++++++++++ app/Repositories/ToolRepository.php | 26 +++++++ ..._add_permission_to_staffmessages_table.php | 32 +++++++++ include/functions.php | 47 ++++++++----- include/globalfunctions.php | 38 +++++++---- nexus/Plugin/Hook.php | 4 +- nexus/Plugin/Plugin.php | 2 +- public/announce.php | 2 +- public/staffbox.php | 67 ++++++++++++------- public/takeedit.php | 4 +- 11 files changed, 219 insertions(+), 59 deletions(-) create mode 100644 database/migrations/2022_08_22_030816_add_permission_to_staffmessages_table.php diff --git a/app/Models/StaffMessage.php b/app/Models/StaffMessage.php index 5a688078..aab5c8a7 100644 --- a/app/Models/StaffMessage.php +++ b/app/Models/StaffMessage.php @@ -2,12 +2,15 @@ namespace App\Models; +use App\Repositories\ToolRepository; +use Google\Service\Testing\ToolResultsExecution; + class StaffMessage extends NexusModel { protected $table = 'staffmessages'; protected $fillable = [ - 'sender', 'added', 'subject', 'msg', 'answeredby', 'answered', 'answer' + 'sender', 'added', 'subject', 'msg', 'answeredby', 'answered', 'answer', 'permission', ]; protected $casts = [ diff --git a/app/Repositories/MessageRepository.php b/app/Repositories/MessageRepository.php index 853fc26e..2cb3d359 100644 --- a/app/Repositories/MessageRepository.php +++ b/app/Repositories/MessageRepository.php @@ -2,11 +2,18 @@ namespace App\Repositories; use App\Models\Message; +use App\Models\Setting; +use App\Models\StaffMessage; use App\Models\User; use Illuminate\Support\Facades\DB; +use Nexus\Database\NexusDB; class MessageRepository extends BaseRepository { + const STAFF_MESSAGE_TOTAL_CACHE_KEY = 'staff_message_count'; + + const STAFF_MESSAGE_NEW_CACHE_KEY = 'staff_new_message_count'; + public function getList(array $params) { $query = Message::query(); @@ -40,4 +47,48 @@ class MessageRepository extends BaseRepository $result = $model->delete(); return $result; } + + public static function countStaffMessage($uid, $answered = null): int + { + return self::buildStaffMessageQuery($uid, $answered)->count(); + } + + public static function buildStaffMessageQuery($uid, $answered = null): \Illuminate\Database\Eloquent\Builder + { + $query = StaffMessage::query(); + if ($answered !== null) { + $query->where('answered', $answered); + } + if (!user_can('staffmem', false, $uid)) { + //Not staff member only can see authorized + $permissions = ToolRepository::listUserAllPermissions($uid); + $query->whereIn('permission', $permissions); + } + return $query; + } + + public static function updateStaffMessageCountCache($uid = 0, $type = '', $value = '') + { + if ($uid === false) { + NexusDB::cache_del(self::STAFF_MESSAGE_NEW_CACHE_KEY); + NexusDB::cache_del(self::STAFF_MESSAGE_TOTAL_CACHE_KEY); + } else { + $redis = NexusDB::redis(); + match ($type) { + 'total' => $redis->hSet(self::STAFF_MESSAGE_TOTAL_CACHE_KEY, $uid, $value), + 'new' => $redis->hSet(self::STAFF_MESSAGE_NEW_CACHE_KEY, $uid, $value), + default => throw new \InvalidArgumentException("Invalid type: $type") + }; + } + } + + public static function getStaffMessageCountCache($uid = 0, $type = '') + { + $redis = NexusDB::redis(); + return match ($type) { + 'total' => $redis->hGet(self::STAFF_MESSAGE_TOTAL_CACHE_KEY, $uid), + 'new' => $redis->hGet(self::STAFF_MESSAGE_NEW_CACHE_KEY, $uid), + default => throw new \InvalidArgumentException("Invalid type: $type") + }; + } } diff --git a/app/Repositories/ToolRepository.php b/app/Repositories/ToolRepository.php index 2d5e5d2d..d11ae85c 100644 --- a/app/Repositories/ToolRepository.php +++ b/app/Repositories/ToolRepository.php @@ -8,7 +8,11 @@ use App\Models\PollAnswer; use App\Models\Setting; use App\Models\User; use Carbon\Carbon; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\Storage; +use Nexus\Database\NexusDB; +use Nexus\Plugin\Plugin; +use NexusPlugin\Permission\PermissionRepository; use Symfony\Component\Mailer\Transport\Dsn; use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransportFactory; use Symfony\Component\Mailer\Mailer; @@ -360,5 +364,27 @@ class ToolRepository extends BaseRepository return $result; } + public static function listUserClassPermissions($uid): array + { + $userInfo = get_user_row($uid); + $prefix = "authority"; + $excludes = collect(Setting::$permissionMustHaveClass)->map(fn ($p) => "$prefix.$p")->toArray(); + return Setting::query() + ->where("name", "like", "$prefix.%") + ->whereNotIn('name', $excludes) + ->where('value', '<=', $userInfo['class']) + ->where('value', '>=', User::CLASS_PEASANT) + ->pluck('name') + ->map(fn ($name) => str_replace("$prefix.", "", $name)) + ->toArray(); + } + + public static function listUserAllPermissions($uid): array + { + return NexusDB::remember("user_{$uid}_permissions", 600, function () use ($uid) { + $classPermissions = self::listUserClassPermissions($uid); + return apply_filter('user_permissions', $classPermissions, $uid); + }); + } } diff --git a/database/migrations/2022_08_22_030816_add_permission_to_staffmessages_table.php b/database/migrations/2022_08_22_030816_add_permission_to_staffmessages_table.php new file mode 100644 index 00000000..f2b338af --- /dev/null +++ b/database/migrations/2022_08_22_030816_add_permission_to_staffmessages_table.php @@ -0,0 +1,32 @@ +string('permission')->nullable(false)->default('')->index(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('staffmessages', function (Blueprint $table) { + $table->dropColumn('permission'); + }); + } +}; diff --git a/include/functions.php b/include/functions.php index 13d4e8ad..47b0851f 100644 --- a/include/functions.php +++ b/include/functions.php @@ -2693,18 +2693,28 @@ else { $totalreports = get_row_count("reports"); $Cache->cache_value('staff_report_count', $totalreports, 900); } - $totalsm = $Cache->get_value('staff_message_count'); - if ($totalsm == ""){ - $totalsm = get_row_count("staffmessages"); - $Cache->cache_value('staff_message_count', $totalsm, 900); - } $totalcheaters = $Cache->get_value('staff_cheater_count'); if ($totalcheaters == ""){ $totalcheaters = get_row_count("cheaters"); $Cache->cache_value('staff_cheater_count', $totalcheaters, 900); } - print("\"cheaterbox\" ".$totalcheaters." \"reportbox\" ".$totalreports." \"staffbox\" ".$totalsm." "); + print( + "\"cheaterbox\" ".$totalcheaters + ." \"reportbox\" ".$totalreports + ); } +// $cacheKey = "staff_message_count_" . $CURUSER['id']; +// $totalsm = $Cache->get_value($cacheKey); + $totalsm = \App\Repositories\MessageRepository::getStaffMessageCountCache($CURUSER['id'], 'total'); + + if ($totalsm == ""){ + $totalsm = \App\Repositories\MessageRepository::countStaffMessage($CURUSER['id']); +// $Cache->cache_value($cacheKey, $totalsm, 900); + \App\Repositories\MessageRepository::updateStaffMessageCountCache($CURUSER['id'], 'total', $totalsm); + } + if ($totalsm > 0) { + print (" \"staffbox\" ".$totalsm." "); + } print("".$inboxpic." ".($messages ? $messages." (".$unread.$lang_functions['text_message_new'].")" : "0")); print(" \"sentbox\" ".($outmessages ? $outmessages : "0")); @@ -2795,6 +2805,21 @@ if ($msgalert) } } + //Staff message, not only staff member +// $cacheKey = 'staff_new_message_count_' . $CURUSER['id']; +// $nummessages = $Cache->get_value($cacheKey); + $nummessages = \App\Repositories\MessageRepository::getStaffMessageCountCache($CURUSER['id'], 'new'); + + if ($nummessages == ""){ + $nummessages = \App\Repositories\MessageRepository::countStaffMessage($CURUSER['id'], 0); +// $Cache->cache_value($cacheKey, $nummessages, 900); + \App\Repositories\MessageRepository::updateStaffMessageCountCache($CURUSER['id'], 'new', $nummessages); + } + if ($nummessages > 0) { + $text = $lang_functions['text_there_is'].is_or_are($nummessages).$nummessages.$lang_functions['text_new_staff_message'] . add_s($nummessages); + msgalert("staffbox.php",$text, "blue"); + } + if (user_can('staffmem')) { //torrent approval @@ -2827,15 +2852,7 @@ if ($msgalert) $text = $lang_functions['text_there_is'].is_or_are($numreports).$numreports.$lang_functions['text_new_report'] .add_s($numreports); msgalert("reports.php",$text, "blue"); } - $nummessages = $Cache->get_value('staff_new_message_count'); - if ($nummessages == ""){ - $nummessages = get_row_count("staffmessages","WHERE answered='no'"); - $Cache->cache_value('staff_new_message_count', $nummessages, 900); - } - if ($nummessages > 0) { - $text = $lang_functions['text_there_is'].is_or_are($nummessages).$nummessages.$lang_functions['text_new_staff_message'] . add_s($nummessages); - msgalert("staffbox.php",$text, "blue"); - } + $numcheaters = $Cache->get_value('staff_new_cheater_count'); if ($numcheaters == ""){ $numcheaters = get_row_count("cheaters","WHERE dealtwith=0"); diff --git a/include/globalfunctions.php b/include/globalfunctions.php index f323497e..2d510155 100644 --- a/include/globalfunctions.php +++ b/include/globalfunctions.php @@ -1,7 +1,5 @@ = 0 && $requireClass < $userInfo['class']; - $log .= ", requireClass: $requireClass, result: $result"; - } else { - $log .= ", get result: $result from filter nexus_user_can"; - } + $userAllPermissions = \App\Repositories\ToolRepository::listUserAllPermissions($uid); + $result = in_array($permission, $userAllPermissions); + $log .= ", userAllPermissions: " . json_encode($userAllPermissions) . ", result: $result"; if (!$fail || $result) { do_log($log); + $userCanCached[$permission][$uid] = $result; return $result; } do_log("$log, [FAIL]"); if (IN_NEXUS && !IN_TRACKER) { global $lang_functions; - if (isset(User::$classes[$requireClass])) { + $requireClass = get_setting("authority.$permission"); + if (isset(\App\Models\User::$classes[$requireClass])) { stderr($lang_functions['std_sorry'],$lang_functions['std_permission_denied_only'].get_user_class_name($requireClass,false,true,true).$lang_functions['std_or_above_can_view'],false); } else { stderr($lang_functions['std_error'], $lang_functions['std_permission_denied']); diff --git a/nexus/Plugin/Hook.php b/nexus/Plugin/Hook.php index fe0edadd..26afd020 100644 --- a/nexus/Plugin/Hook.php +++ b/nexus/Plugin/Hook.php @@ -32,7 +32,7 @@ class Hook public function applyFilter($name, $value = '') { if (!isset(self::$callbacks[$name])) { - do_log("No this hook: $name"); + do_log("No this hook: $name", 'debug'); return $value; } $args = func_get_args(); @@ -59,7 +59,7 @@ class Hook public function doAction($name, $value = '') { if (!isset(self::$callbacks[$name])) { - do_log("No this hook: $name"); + do_log("No this hook: $name", 'debug'); return; } $args = func_get_args(); diff --git a/nexus/Plugin/Plugin.php b/nexus/Plugin/Plugin.php index 6e0c78e6..f1193af4 100644 --- a/nexus/Plugin/Plugin.php +++ b/nexus/Plugin/Plugin.php @@ -11,7 +11,7 @@ class Plugin $this->bootPlugins(); } - public function enabled($name): bool + public static function enabled($name): bool { return !empty(self::$providers[$name]['providers']); } diff --git a/public/announce.php b/public/announce.php index 2fb00718..4701f8ea 100644 --- a/public/announce.php +++ b/public/announce.php @@ -172,7 +172,7 @@ if (!$torrent) { do_log("[TORRENT NOT EXISTS] infoHashUrlEncode: $infoHashUrlEncode", 'error'); err("torrent not registered with this tracker"); -} elseif ($az['class'] < $seebanned_class) { +} elseif (!user_can('seebanned', false, $userid)) { if ($torrent['banned'] == 'yes') { err("torrent banned"); } elseif ($torrent['approval_status'] != \App\Models\Torrent::APPROVAL_STATUS_ALLOW && get_setting('torrent.approval_status_none_visible') == 'no') { diff --git a/public/staffbox.php b/public/staffbox.php index 6eb41d23..b865cab5 100644 --- a/public/staffbox.php +++ b/public/staffbox.php @@ -3,10 +3,23 @@ require "../include/bittorrent.php"; dbconn(); require_once(get_langfile_path()); loggedinorreturn(); -user_can('staffmem', true); $action = $_GET["action"] ?? ''; +function can_access_staff_message($msg) +{ + global $CURUSER; + if (user_can('staffmem')) { + return true; + } + if (is_numeric($msg)) { + $msg = \App\Models\StaffMessage::query()->findOrFail($msg)->toArray(); + } + if (empty($msg['permission']) || !in_array($msg['permission'], \App\Repositories\ToolRepository::listUserAllPermissions($CURUSER['id']))) { + permissiondenied(get_setting('authority.staffmem')); + } +} + /////////////////////////// // SHOW PM'S // ///////////////////////// @@ -14,12 +27,14 @@ $action = $_GET["action"] ?? ''; if (!$action) { stdhead($lang_staffbox['head_staff_pm']); $url = $_SERVER['PHP_SELF']."?"; - $count = get_row_count("staffmessages"); + $query = \App\Repositories\MessageRepository::buildStaffMessageQuery($CURUSER['id']); + $count = $query->count(); $perpage = 20; - list($pagertop, $pagerbottom, $limit) = pager($perpage, $count, $url); + list($pagertop, $pagerbottom, $limit, $offset, $pageSize, $pageNum) = pager($perpage, $count, $url); print ("

".$lang_staffbox['text_staff_pm']."

"); if ($count == 0) { + do_log(last_query()); stdmsg($lang_staffbox['std_sorry'], $lang_staffbox['std_no_messages_yet']); } else @@ -35,9 +50,9 @@ if (!$action) { ".$lang_staffbox['col_action']." "); - $res = sql_query("SELECT staffmessages.id, staffmessages.added, staffmessages.subject, staffmessages.answered, staffmessages.answeredby, staffmessages.sender, staffmessages.answer FROM staffmessages ORDER BY id desc $limit"); - - while ($arr = mysql_fetch_assoc($res)) + $res = $query->forPage($pageNum, $perpage)->orderBy('id', 'desc')->get()->toArray(); + do_log(last_query()); + foreach ($res as $arr) { if ($arr['answered']) { @@ -64,13 +79,11 @@ if (!$action) { if ($action == "viewpm") { - user_can('staffmem', true); - $pmid = intval($_GET["pmid"] ?? 0); $ress4 = sql_query("SELECT * FROM staffmessages WHERE id=".sqlesc($pmid)); $arr4 = mysql_fetch_assoc($ress4); - +can_access_staff_message($arr4); $answeredby = get_username($arr4["answeredby"]); if (is_valid_id($arr4["sender"])) @@ -120,8 +133,6 @@ stdfoot(); ////////////////////////// if ($action == "answermessage") { - user_can('staffmem', true); - $answeringto = $_GET["answeringto"]; $receiver = intval($_GET["receiver"] ?? 0); @@ -135,6 +146,9 @@ if ($action == "answermessage") { $res2 = sql_query("SELECT * FROM staffmessages WHERE id=" . sqlesc($answeringto)); $staffmsg = mysql_fetch_assoc($res2); + + can_access_staff_message($staffmsg); + stdhead($lang_staffbox['head_answer_to_staff_pm']); begin_main_frame(); ?> @@ -160,8 +174,6 @@ if ($action == "takeanswer") { if ($_SERVER["REQUEST_METHOD"] != "POST") die(); - user_can('staffmem', true); - $receiver = intval($_POST["receiver"] ?? 0); $answeringto = $_POST["answeringto"]; @@ -178,10 +190,13 @@ if ($action == "takeanswer") { if (!$msg) stderr($lang_staffbox['std_error'], $lang_staffbox['std_body_is_empty']); + can_access_staff_message($answeringto); + sql_query("INSERT INTO messages (sender, receiver, added, msg) VALUES($userid, $receiver, $added, $message)") or sqlerr(__FILE__, __LINE__); sql_query("UPDATE staffmessages SET answer=$message, answered='1', answeredby='$userid' WHERE id=$answeringto") or sqlerr(__FILE__, __LINE__); $Cache->delete_value('staff_new_message_count'); +clear_staff_message_cache(); header("Location: staffbox.php?action=viewpm&pmid=$answeringto"); die; } @@ -196,11 +211,11 @@ if ($action == "deletestaffmessage") { if (!is_numeric($id) || $id < 1 || floor($id) != $id) die; - user_can('staffmem', true); - + can_access_staff_message($id); sql_query("DELETE FROM staffmessages WHERE id=" . sqlesc($id)) or die(); $Cache->delete_value('staff_message_count'); $Cache->delete_value('staff_new_message_count'); +clear_staff_message_cache(); header("Location: " . get_protocol_prefix() . "$BASEURL/staffbox.php"); } @@ -210,12 +225,12 @@ $Cache->delete_value('staff_new_message_count'); if ($action == "setanswered") { - user_can('staffmem', true); $id = intval($_GET["id"] ?? 0); - + can_access_staff_message($id); sql_query ("UPDATE staffmessages SET answered=1, answeredby = {$CURUSER['id']} WHERE id = $id") or sqlerr(); $Cache->delete_value('staff_new_message_count'); + clear_staff_message_cache(); header("Refresh: 0; url=staffbox.php?action=viewpm&pmid=$id"); } @@ -224,19 +239,23 @@ header("Refresh: 0; url=staffbox.php?action=viewpm&pmid=$id"); ////////////////////////// if ($action == "takecontactanswered") { - user_can('staffmem', true); if ($_POST['setdealt']){ - $res = sql_query ("SELECT id FROM staffmessages WHERE answered=0 AND id IN (" . implode(", ", $_POST['setanswered']) . ")"); - while ($arr = mysql_fetch_assoc($res)) - sql_query ("UPDATE staffmessages SET answered=1, answeredby = {$CURUSER['id']} WHERE id = {$arr['id']}") or sqlerr(); + $res = sql_query ("SELECT * FROM staffmessages WHERE answered=0 AND id IN (" . implode(", ", $_POST['setanswered']) . ")"); + while ($arr = mysql_fetch_assoc($res)) { + can_access_staff_message($arr); + sql_query ("UPDATE staffmessages SET answered=1, answeredby = {$CURUSER['id']} WHERE id = {$arr['id']}") or sqlerr(); + } } elseif ($_POST['delete']){ - $res = sql_query ("SELECT id FROM staffmessages WHERE id IN (" . implode(", ", $_POST['setanswered']) . ")"); - while ($arr = mysql_fetch_assoc($res)) - sql_query ("DELETE FROM staffmessages WHERE id = {$arr['id']}") or sqlerr(); + $res = sql_query ("SELECT * FROM staffmessages WHERE id IN (" . implode(", ", $_POST['setanswered']) . ")"); + while ($arr = mysql_fetch_assoc($res)) { + can_access_staff_message($arr); + sql_query ("DELETE FROM staffmessages WHERE id = {$arr['id']}") or sqlerr(); + } } $Cache->delete_value('staff_new_message_count'); + clear_staff_message_cache(); header("Refresh: 0; url=staffbox.php"); } diff --git a/public/takeedit.php b/public/takeedit.php index 2352112f..2d72ba7d 100644 --- a/public/takeedit.php +++ b/public/takeedit.php @@ -258,9 +258,9 @@ if ($affectedRows == 1 && $row['banned'] == 'yes' && $row['owner'] == $CURUSER[' 'subject' => nexus_trans('torrent.owner_update_torrent_subject', ['detail_url' => $torrentUrl, 'torrent_name' => $_POST['name']]), 'msg' => nexus_trans('torrent.owner_update_torrent_msg', ['detail_url' => $torrentUrl, 'torrent_name' => $_POST['name']]), 'added' => now(), + 'permission' => 'torrent-approval', ]); - \Nexus\Database\NexusDB::cache_del("staff_new_message_count"); - \Nexus\Database\NexusDB::cache_del("staff_message_count"); + clear_staff_message_cache(); } $returl = "details.php?id=$id&edited=1";