user ban log

This commit is contained in:
xiaomlove
2021-05-12 13:45:00 +08:00
parent 02d7eb4e93
commit 70f1f31dcc
18 changed files with 107 additions and 217 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ class InviteResource extends JsonResource
return [
'id' => $this->id,
'inviter' => $this->inviter,
'invitee' => $this->inviter,
'invitee' => $this->invitee,
'hash' => $this->hash,
'time_invited' => $this->time_invited,
'valid' => $this->valid,
+1 -1
View File
@@ -32,7 +32,7 @@ class UserResource extends JsonResource
'seedtime_text' => mkprettytime($this->seedtime),
'leechtime' => $this->leechtime,
'leechtime_text' => mkprettytime($this->leechtime),
'invitee_code' => new InviteResource($this->whenLoaded('invitee_code')),
'inviter' => new UserResource($this->whenLoaded('inviter')),
];
}
}
+7 -1
View File
@@ -103,7 +103,8 @@ class User extends Authenticatable
public static $commonFields = [
'id', 'username', 'email', 'class', 'status', 'added', 'avatar',
'uploaded', 'downloaded', 'seedbonus', 'seedtime', 'leechtime'
'uploaded', 'downloaded', 'seedbonus', 'seedtime', 'leechtime',
'invited_by',
];
public function checkIsNormal(array $fields = ['status', 'enabled'])
@@ -139,4 +140,9 @@ class User extends Authenticatable
return $this->hasOne(Invite::class, 'invitee_register_uid');
}
public function inviter()
{
return $this->belongsTo(User::class, 'invited_by');
}
}
+9
View File
@@ -0,0 +1,9 @@
<?php
namespace App\Models;
class UserBanLog extends NexusModel
{
protected $table = 'user_ban_logs';
}
+33 -4
View File
@@ -9,6 +9,7 @@ use App\Models\Message;
use App\Models\Setting;
use App\Models\Torrent;
use App\Models\User;
use App\Models\UserBanLog;
use Carbon\Carbon;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Arr;
@@ -502,6 +503,7 @@ class ExamRepository extends BaseRepository
$now = Carbon::now()->toDateTimeString();
$examUserTable = (new ExamUser())->getTable();
$examTable = (new Exam())->getTable();
$userTable = (new User())->getTable();
$baseQuery = ExamUser::query()
->join($examTable, "$examUserTable.exam_id", "=", "$examTable.id")
->where("$examUserTable.status", ExamUser::STATUS_NORMAL)
@@ -519,6 +521,7 @@ class ExamRepository extends BaseRepository
$size = 100;
$minId = 0;
$result = 0;
while (true) {
$logPrefix = sprintf('[%s], size: %s', __FUNCTION__, $size);
$examUsers = (clone $baseQuery)->where("$examUserTable.id", ">", $minId)->limit($size)->get();
@@ -530,11 +533,12 @@ class ExamRepository extends BaseRepository
}
$result += $examUsers->count();
$now = Carbon::now()->toDateTimeString();
$examUserIdArr = $uidToDisable = $messageToSend = [];
$examUserIdArr = $uidToDisable = $messageToSend = $userBanLog = $userModcommentUpdate = [];
foreach ($examUsers as $examUser) {
$minId = $examUser->id;
$examUserIdArr[] = $examUser->id;
$uid = $examUser->uid;
$exam = $examUser->exam;
$currentLogPrefix = sprintf("$logPrefix, user: %s, exam: %s, examUser: %s", $uid, $examUser->exam_id, $examUser->id);
$locale = $examUser->user->locale;
if ($examUser->is_done) {
@@ -547,10 +551,26 @@ class ExamRepository extends BaseRepository
$msgTransKey = 'exam.checkout_not_pass_message_content';
//ban user
$uidToDisable[] = $uid;
$userModcomment = nexus_trans('exam.ban_user_modcomment', [
'exam_name' => $exam->name,
'begin' => $examUser->begin,
'end' => $examUser->end
], $locale);
$userModcommentUpdate[] = sprintf("when `id` = %s then concat_ws('\n', modcomment, '%s')", $uid, $userModcomment);
$banLogReason = nexus_trans('exam.ban_log_reason', [
'exam_name' => $exam->name,
'begin' => $exam->begin,
'end' => $exam->end,
], $locale);
$userBanLog[] = [
'uid' => $uid,
'username' => $examUser->user->username,
'reason' => $banLogReason,
];
}
$subject = nexus_trans($subjectTransKey, [], $locale);
$msg = nexus_trans($msgTransKey, [
'exam_name' => $examUser->exam->name,
'exam_name' => $exam->name,
'begin' => $examUser->begin,
'end' => $examUser->end
], $locale);
@@ -561,11 +581,20 @@ class ExamRepository extends BaseRepository
'msg' => $msg
];
}
DB::transaction(function () use ($uidToDisable, $messageToSend, $examUserIdArr) {
DB::transaction(function () use ($uidToDisable, $messageToSend, $examUserIdArr, $userBanLog, $userModcommentUpdate, $userTable, $logPrefix) {
ExamUser::query()->whereIn('id', $examUserIdArr)->update(['status' => ExamUser::STATUS_FINISHED]);
Message::query()->insert($messageToSend);
if (!empty($uidToDisable)) {
User::query()->whereIn('id', $uidToDisable)->update(['enabled' => User::ENABLED_NO]);
$uidStr = implode(', ', $uidToDisable);
$sql = sprintf(
'update %s set enabled = %s, set modcomment = case when %s end where id in (%s)',
$userTable, User::ENABLED_NO, implode(' ', $userModcommentUpdate), $uidStr
);
$updateResult = DB::update($sql);
do_log(sprintf("$logPrefix, disable %s users: %s, sql: %s, updateResult: %s", count($uidToDisable), $uidStr, $sql, $updateResult));
}
if (!empty($userBanLog)) {
UserBanLog::query()->insert($userBanLog);
}
});
}
+5 -1
View File
@@ -6,6 +6,7 @@ use App\Http\Resources\UserResource;
use App\Models\ExamUser;
use App\Models\Setting;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
class UserRepository extends BaseRepository
{
@@ -25,7 +26,10 @@ class UserRepository extends BaseRepository
public function getDetail($id)
{
$user = User::query()->with(['invitee_code'])->findOrFail($id, User::$commonFields);
$with = [
'inviter' => function (Builder $query) {return $query->select(User::$commonFields);}
];
$user = User::query()->with($with)->findOrFail($id, User::$commonFields);
$userResource = new UserResource($user);
$baseInfo = $userResource->response()->getData(true)['data'];
@@ -1,36 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateFailedJobsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->string('uuid')->unique();
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('failed_jobs');
}
}
@@ -1,36 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePersonalAccessTokensTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->bigIncrements('id');
$table->morphs('tokenable');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('personal_access_tokens');
}
}
@@ -1,40 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateExamsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('exams', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description')->nullable();
$table->dateTime('begin')->nullable();
$table->dateTime('end')->nullable();
$table->integer('duration')->default(0);
$table->text('filters')->nullable();
$table->text('indexes');
$table->tinyInteger('status')->default(0);
$table->tinyInteger('is_discovered')->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('exams');
}
}
@@ -1,38 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateExamProgressTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('exam_progress', function (Blueprint $table) {
$table->id();
$table->integer('exam_user_id')->index();
$table->integer('exam_id')->index();
$table->integer('uid')->index();
$table->integer('torrent_id');
$table->integer('index');
$table->bigInteger('value');
$table->timestamps();
$table->index('created_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('exam_progress');
}
}
@@ -1,38 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateExamUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('exam_users', function (Blueprint $table) {
$table->id();
$table->integer('uid')->index();
$table->integer('exam_id')->index();
$table->integer('status')->default(0);
$table->dateTime('begin')->nullable();
$table->dateTime('end')->nullable();
$table->text('progress')->nullable();
$table->tinyInteger('is_done')->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('exam_users');
}
}
+30 -21
View File
@@ -29,7 +29,7 @@ if ($action == "edituser")
$class = intval($_POST["class"] ?? 0);
$vip_added = ($_POST["vip_added"] == 'yes' ? 'yes' : 'no');
$vip_until = ($_POST["vip_until"] ? $_POST["vip_until"] : null);
$warned = $_POST["warned"] ?? '';
$warnlength = intval($_POST["warnlength"] ?? 0);
$warnpm = $_POST["warnpm"];
@@ -46,22 +46,23 @@ if ($action == "edituser")
$forumpost = $_POST["forumpost"];
$chpassword = $_POST["chpassword"];
$passagain = $_POST["passagain"];
$supportlang = $_POST["supportlang"];
$support = $_POST["support"];
$supportfor = $_POST["supportfor"];
$supportfor = $_POST["supportfor"];
$moviepicker = $_POST["moviepicker"];
$pickfor = $_POST["pickfor"];
$stafffor = $_POST["staffduties"];
if (!is_valid_id($userid) || !is_valid_user_class($class))
stderr("Error", "Bad user ID or class ID.");
if (get_user_class() <= $class)
stderr("Error", "You have no permission to change user's class to ".get_user_class_name($class,false,false,true).". BTW, how do you get here?");
$res = sql_query("SELECT * FROM users WHERE id = ".sqlesc($userid)) or sqlerr(__FILE__, __LINE__);
$arr = mysql_fetch_assoc($res) or puke();
$user = \App\Models\User::query()->findOrFail($userid);
$curenabled = $arr["enabled"];
$curparked = $arr["parked"];
$curuploadpos = $arr["uploadpos"];
@@ -69,7 +70,7 @@ if ($action == "edituser")
$curforumpost = $arr["forumpost"];
$curclass = $arr["class"];
$curwarned = $arr["warned"];
$updateset[] = "stafffor = " . sqlesc($stafffor);
$updateset[] = "pickfor = " . sqlesc($pickfor);
$updateset[] = "picker = " . sqlesc($moviepicker);
@@ -83,7 +84,8 @@ if ($action == "edituser")
$updateset[] = "support = " . sqlesc($support);
$updateset[] = "supportfor = " . sqlesc($supportfor);
$updateset[] = "supportlang = ".sqlesc($supportlang);
$banLog = [];
if(get_user_class()<=$cruprfmanage_class)
{
$modcomment = $arr["modcomment"];
@@ -152,7 +154,7 @@ if ($action == "edituser")
$this_donated_usd = $donated - $arr["donated"];
$this_donated_cny = $donated_cny - $arr["donated_cny"];
$memo = sqlesc(htmlspecialchars($_POST["donation_memo"]));
if ($donated != $arr['donated'] || $donated_cny != $arr['donated_cny']) {
$added = sqlesc(date("Y-m-d H:i:s"));
sql_query("INSERT INTO funds (usd, cny, user, added, memo) VALUES ($this_donated_usd, $this_donated_cny, $userid, $added, $memo)") or sqlerr(__FILE__, __LINE__);
@@ -162,17 +164,17 @@ if ($action == "edituser")
$updateset[] = "donor = " . sqlesc($donor);
}
if ($chpassword != "" AND $passagain != "") {
unset($passupdate);
$passupdate=false;
if ($chpassword == $username OR strlen($chpassword) > 40 OR strlen($chpassword) < 6 OR $chpassword != $passagain)
$passupdate=false;
else
$passupdate=true;
}
if (isset($passupdate) && $passupdate) {
$sec = mksecret();
$passhash = md5($sec . $chpassword . $sec);
@@ -205,7 +207,7 @@ if ($action == "edituser")
sql_query("INSERT INTO messages (sender, receiver, subject, msg, added) VALUES (0, $userid, $subject, $msg, $added)") or sqlerr(__FILE__, __LINE__);
$modcomment = date("Y-m-d") . " - VIP status changed by {$CURUSER['username']}. VIP added: ".$vip_added.($vip_added == 'yes' ? "; VIP until: ".$vip_until : "").".\n". $modcomment;
}
if ($warned && $curwarned != $warned)
{
$updateset[] = "warned = " . sqlesc($warned);
@@ -229,7 +231,7 @@ if ($action == "edituser")
$msg = sqlesc($lang_modtask_target[get_user_lang($userid)]['msg_you_are_warned_by'].$CURUSER['username']."." . ($warnpm ? $lang_modtask_target[get_user_lang($userid)]['msg_reason'].$warnpm : ""));
$updateset[] = "warneduntil = null";
}else{
$warneduntil = date("Y-m-d H:i:s",(strtotime(date("Y-m-d H:i:s")) + $warnlength * 604800));
$warneduntil = date("Y-m-d H:i:s",(strtotime(date("Y-m-d H:i:s")) + $warnlength * 604800));
$dur = $warnlength . $lang_modtask_target[get_user_lang($userid)]['msg_week'] . ($warnlength > 1 ? $lang_modtask_target[get_user_lang($userid)]['msg_s'] : "");
$msg = sqlesc($lang_modtask_target[get_user_lang($userid)]['msg_you_are_warned_for'].$dur.$lang_modtask_target[get_user_lang($userid)]['msg_by'] . $CURUSER['username'] . "." . ($warnpm ? $lang_modtask_target[get_user_lang($userid)]['msg_reason'].$warnpm : ""));
$modcomment = date("Y-m-d") . " - Warned for $dur by " . $CURUSER['username'] . ".\nReason: $warnpm.\n". $modcomment;
@@ -253,7 +255,12 @@ if ($action == "edituser")
sql_query("UPDATE users SET enabled='yes', leechwarn='no' WHERE id = ".sqlesc($userid)) or sqlerr(__FILE__, __LINE__);
}
} else {
$modcomment = date("Y-m-d") . " - Disabled by " . $CURUSER['username']. ".\n". $modcomment;
$modcomment = date("Y-m-d") . " - Disabled by " . $CURUSER['username']. ".\n". $modcomment;
$banLog = [
'uid' => $userid,
'username' => $user->username,
'reason' => nexus_trans('user.edit_ban_reason', [], $user->locale),
];
}
}
if ($arr['noad'] != $noad){
@@ -266,7 +273,7 @@ if ($action == "edituser")
}
if ($privacy == "low" OR $privacy == "normal" OR $privacy == "strong")
$updateset[] = "privacy = " . sqlesc($privacy);
if (isset($_POST["resetkey"]) && $_POST["resetkey"] == "yes")
{
$newpasskey = md5($arr['username'].date("Y-m-d H:i:s").$arr['passhash']);
@@ -328,12 +335,14 @@ if ($action == "edituser")
$added = sqlesc(date("Y-m-d H:i:s"));
sql_query("INSERT INTO messages (sender, receiver, subject, msg, added) VALUES (0, $userid, $subject, $msg, $added)") or sqlerr(__FILE__, __LINE__);
}
}
$updateset[] = "modcomment = " . sqlesc($modcomment);
sql_query("UPDATE users SET " . implode(", ", $updateset) . " WHERE id=$userid") or sqlerr(__FILE__, __LINE__);
}
$updateset[] = "modcomment = " . sqlesc($modcomment);
sql_query("UPDATE users SET " . implode(", ", $updateset) . " WHERE id=$userid") or sqlerr(__FILE__, __LINE__);
if (!empty($banLog)) {
\App\Models\UserBanLog::query()->insert($banLog);
}
$returnto = htmlspecialchars($_POST["returnto"]);
header("Location: " . get_protocol_prefix() . "$BASEURL/$returnto");
die;
+2
View File
@@ -17,4 +17,6 @@ return [
'checkout_pass_message_content' => 'Congratulation! You have complete the exam: :exam_name in time(:begin ~ :end)',
'checkout_not_pass_message_subject' => 'Exam not pass, and account is banned!',
'checkout_not_pass_message_content' => 'You did not complete the exam: :exam_name in time(:begin ~ :end), and your account has be banned!',
'ban_log_reason' => 'Not complete exam: :exam_name in time(:begin ~ :end)',
'ban_user_modcomment' => 'Due to not complete exam: :exam_name(:begin ~ :end), ban by system',
];
+5
View File
@@ -0,0 +1,5 @@
<?php
return [
'edit_ban_reason' => 'Disable by administrator',
];
+2
View File
@@ -17,4 +17,6 @@ return [
'checkout_pass_message_content' => '恭喜!你在规定时间内(:begin ~ :end)顺利完成了考核::exam_name。',
'checkout_not_pass_message_subject' => '考核未通过,账号被禁用!',
'checkout_not_pass_message_content' => '你在规定时间内(:begin ~ :end)未完成考核::exam_name,账号已被禁用。',
'ban_log_reason' => '未完成考核::exam_name(:begin ~ :end)',
'ban_user_modcomment' => '未完成考核: :exam_name(:begin ~ :end), 被系统禁用',
];
+5
View File
@@ -0,0 +1,5 @@
<?php
return [
'edit_ban_reason' => '被管理人员禁用',
];
+2
View File
@@ -17,4 +17,6 @@ return [
'checkout_pass_message_content' => '恭喜!你在規定時間內(:begin ~ :end)順利完成了考核::exam_name。',
'checkout_not_pass_message_subject' => '考核未通過,賬號被禁用!',
'checkout_not_pass_message_content' => '你在規定時間內(:begin ~ :end)未完成考核::exam_name,賬號已被禁用。',
'ban_log_reason' => '未完成考核::exam_name(:begin ~ :end)',
'ban_user_modcomment' => '未完成考核: :exam_name(:begin ~ :end), 被系統禁用',
];
+5
View File
@@ -0,0 +1,5 @@
<?php
return [
'edit_ban_reason' => '被管理人員禁用',
];