feat(super_manage): submission_frequency config

This commit is contained in:
Baoshuo Ren 2023-02-14 11:36:10 +08:00
parent 0f3099bbe5
commit a483cc598b
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
3 changed files with 89 additions and 62 deletions

View File

@ -38,6 +38,10 @@ $tabs_info = [
'name' => '图床管理', 'name' => '图床管理',
'url' => "/super_manage/image_hosting", 'url' => "/super_manage/image_hosting",
], ],
'meta' => [
'name' => 'OJ 基础设置',
'url' => "/super_manage/meta",
],
]; ];
if (!isset($tabs_info[$cur_tab])) { if (!isset($tabs_info[$cur_tab])) {
@ -1068,6 +1072,41 @@ if ($cur_tab == 'index') {
]); ]);
}; };
$change_user_image_total_size_limit_form->runAtServer(); $change_user_image_total_size_limit_form->runAtServer();
} elseif ($cur_tab == 'meta') {
$submission_frequency = UOJContext::getMeta('submission_frequency');
$submission_frequency_form = new UOJForm('submission_frequency');
$submission_frequency_form->addSelect('submission_frequency_interval', [
'label' => '时间间隔',
'options' => [
'PT1S' => '1 秒',
'PT10S' => '10 秒',
'PT1M' => '1 分钟',
'PT10M' => '10 分钟',
'PT30M' => '30 分钟',
'PT1H' => '1 小时',
],
'default_value' => $submission_frequency['interval'],
]);
$submission_frequency_form->addInput('submission_frequency_limit', [
'label' => '最大提交次数',
'help' => '在时间间隔内最多允许提交的次数。',
'default_value' => $submission_frequency['limit'],
'validator_php' => function ($x, &$vdata) {
if (!validateUInt($x)) {
return '不合法';
}
$vdata['limit'] = (int)$x;
return '';
},
]);
$submission_frequency_form->handle = function (&$vdata) {
UOJContext::setMeta('submission_frequency', [
'interval' => UOJRequest::post('submission_frequency_interval'),
'limit' => $vdata['limit'],
]);
};
$submission_frequency_form->succ_href = UOJContext::requestPath() . '#submission-frequency';
$submission_frequency_form->runAtServer();
} }
?> ?>
@ -1463,21 +1502,6 @@ if ($cur_tab == 'index') {
</div> </div>
</div> </div>
</div> </div>
<script>
$(document).ready(function() {
// Javascript to enable link to tab
var hash = location.hash.replace(/^#/, '');
if (hash) {
bootstrap.Tab.jQueryInterface.call($('.nav-tabs a[href="#' + hash + '"]'), 'show').blur();
}
// Change hash for page-reload
$('.nav-tabs a').on('shown.bs.tab', function(e) {
window.location.hash = e.target.hash;
});
});
</script>
<?php elseif ($cur_tab === 'submissions') : ?> <?php elseif ($cur_tab === 'submissions') : ?>
<?php if (!isset($_GET['judging'])) : ?> <?php if (!isset($_GET['judging'])) : ?>
<div> <div>
@ -1660,9 +1684,48 @@ EOD;
<?php $change_user_image_total_size_limit_form->printHTML() ?> <?php $change_user_image_total_size_limit_form->printHTML() ?>
</div> </div>
</div> </div>
<?php elseif ($cur_tab == 'meta') : ?>
<div class="card mt-3 mt-md-0">
<div class="card-header">
<ul class="nav nav-tabs card-header-tabs">
<li class="nav-item">
<a class="nav-link active" href="#submission-frequency" data-bs-toggle="tab" data-bs-target="#submission-frequency">提交频次限制</a>
</li>
</ul>
</div>
<div class="card-body">
<div class="tab-content">
<div class="tab-pane active" id="submission-frequency">
<div class="row">
<div class="col-md-6">
<?php $submission_frequency_form->printHTML() ?>
</div>
<div class="col-md-6">
此处可以设置用户的提交频次限制。请注意,过于严格的限制会导致用户无法正常提交题目。默认限制为 1 秒内最多提交 1 次。
</div>
</div>
</div>
</div>
</div>
</div>
<?php endif ?> <?php endif ?>
</div> </div>
<!-- end right col --> <!-- end right col -->
</div> </div>
<script>
$(document).ready(function() {
// Javascript to enable link to tab
var hash = location.hash.replace(/^#/, '');
if (hash) {
bootstrap.Tab.jQueryInterface.call($('.nav-tabs a[href="#' + hash + '"]'), 'show').blur();
}
// Change hash for page-reload
$('.nav-tabs a').on('shown.bs.tab', function(e) {
window.location.hash = e.target.hash;
});
});
</script>
<?php echoUOJPageFooter() ?> <?php echoUOJPageFooter() ?>

View File

@ -36,8 +36,10 @@ function crsf_defend() {
} }
function submission_frequency_check() { function submission_frequency_check() {
$submission_frequency = UOJContext::getMeta('submission_frequency');
$recent = clone UOJTime::$time_now; $recent = clone UOJTime::$time_now;
$recent->sub(new DateInterval("PT1S")); $recent->sub(new DateInterval($submission_frequency['interval']));
$num = DB::selectCount([ $num = DB::selectCount([
"select count(*) from submissions", "select count(*) from submissions",
"where", [ "where", [
@ -45,54 +47,10 @@ function submission_frequency_check() {
["submit_time", ">=", $recent->format('Y-m-d H:i:s')] ["submit_time", ">=", $recent->format('Y-m-d H:i:s')]
] ]
]); ]);
if ($num >= 1) {
if ($num >= max(1, $submission_frequency['limit'])) {
return false; return false;
} }
// use the implementation below if OJ is under attack
/*
// 1
$recent = clone UOJTime::$time_now;
$recent->sub(new DateInterval("PT3S"));
$num = DB::selectCount([
"select count(*) from submissions",
"where", [
"submitter" => Auth::id(),
["submit_time", ">=", $recent->format('Y-m-d H:i:s')]
]
]);
if ($num >= 1) {
return false;
}
// 2
$recent = clone UOJTime::$time_now;
$recent->sub(new DateInterval("PT1M"));
$num = DB::selectCount([
"select count(*) from submissions",
"where", [
"submitter" => Auth::id(),
["submit_time", ">=", $recent->format('Y-m-d H:i:s')]
]
]);
if ($num >= 6) {
return false;
}
// 3
$recent = clone UOJTime::$time_now;
$recent->sub(new DateInterval("PT30M"));
$num = DB::selectCount([
"select count(*) from submissions",
"where", [
"submitter" => Auth::id(),
["submit_time", ">=", $recent->format('Y-m-d H:i:s')]
]
]);
if ($num >= 30) {
return false;
}
*/
return true; return true;
} }

View File

@ -36,6 +36,10 @@ class UOJContext {
'upload_image' => true, 'upload_image' => true,
], ],
], ],
'submission_frequency' => [
'interval' => 'PT1S',
'limit' => 1,
],
]; ];
public static $data = [ public static $data = [
@ -156,6 +160,7 @@ class UOJContext {
"select value from meta", "select value from meta",
"where", ['name' => $name] "where", ['name' => $name]
]); ]);
if ($value === null) { if ($value === null) {
return self::$meta_default[$name]; return self::$meta_default[$name];
} else { } else {
@ -165,6 +170,7 @@ class UOJContext {
public static function setMeta($name, $value) { public static function setMeta($name, $value) {
$value = json_encode($value); $value = json_encode($value);
return DB::update([ return DB::update([
"insert into meta", DB::bracketed_fields(['name', 'value', 'updated_at']), "insert into meta", DB::bracketed_fields(['name', 'value', 'updated_at']),
"values", DB::tuple([$name, $value, DB::now()]), "values", DB::tuple([$name, $value, DB::now()]),