Merge branch 'master' into remotejudge/uoj-custom-account

This commit is contained in:
Baoshuo Ren 2023-02-03 19:45:03 +08:00
commit 091301d0c8
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
7 changed files with 226 additions and 23 deletions

View File

@ -67,8 +67,8 @@ export default async function daemon(config: UOJConfig) {
if (config.test_sample_only === 'on') {
await request('/submit', {
submit: true,
fetch_new: false,
submit: 1,
fetch_new: 0,
id,
result: JSON.stringify({
status: 'Judged',
@ -80,6 +80,8 @@ export default async function daemon(config: UOJConfig) {
judge_time,
});
await sleep(TIME.second);
continue;
}
@ -115,8 +117,8 @@ export default async function daemon(config: UOJConfig) {
code = fs.readFileSync(sourceCodePath, 'utf-8');
} catch (e) {
await request('/submit', {
submit: true,
fetch_new: false,
submit: 1,
fetch_new: 0,
id,
result: JSON.stringify({
status: 'Judged',
@ -135,6 +137,8 @@ export default async function daemon(config: UOJConfig) {
fs.removeSync(tmpdir);
await sleep(TIME.second);
continue;
}
@ -152,8 +156,8 @@ export default async function daemon(config: UOJConfig) {
);
} catch (err) {
await request('/submit', {
submit: true,
fetch_new: false,
submit: 1,
fetch_new: 0,
id,
result: JSON.stringify({
status: 'Judged',
@ -172,6 +176,8 @@ export default async function daemon(config: UOJConfig) {
}
fs.removeSync(tmpdir);
await sleep(TIME.second);
}
} catch (err) {
logger.error(err.message);

View File

@ -98,8 +98,8 @@ class VJudge {
) {
const next = async payload => {
return await this.request('/submit', {
'update-status': true,
fetch_new: false,
'update-status': 1,
fetch_new: 0,
id,
status:
payload.status ||
@ -110,8 +110,8 @@ class VJudge {
const end = async payload => {
if (payload.error) {
return await this.request('/submit', {
submit: true,
fetch_new: false,
submit: 1,
fetch_new: 0,
id,
result: JSON.stringify({
status: 'Judged',
@ -128,8 +128,8 @@ class VJudge {
}
return await this.request('/submit', {
submit: true,
fetch_new: false,
submit: 1,
fetch_new: 0,
id,
result: JSON.stringify({
status: 'Judged',

View File

@ -0,0 +1,86 @@
<?php
Auth::check() || redirectToLogin();
$type = UOJRequest::get('type', 'is_string', null);
$curl = new Curl\Curl();
$curl->setUserAgent(UOJRemoteProblem::USER_AGENT);
$res = false;
function validateLuogu($response) {
$response = json_decode(json_encode($response), true);
return $response['currentTemplate'] !== 'AuthLogin';
}
if ($type == 'luogu') {
$curl->setFollowLocation();
$curl->setCookie('_uid', UOJRequest::post('_uid', 'is_string', ''));
$curl->setCookie('__client_id', UOJRequest::post('__client_id', 'is_string', ''));
retry_loop(function () use (&$curl, &$res) {
$curl->get(UOJRemoteProblem::$providers['luogu']['url'] . '/user/setting?_contentOnly=1');
if ($curl->error) {
return false;
}
if ($curl->responseHeaders['Content-Type'] == 'text/html') {
$sec = $curl->getResponseCookie('sec');
if ($sec) {
$curl->setCookie('sec', $sec);
$curl->get(UOJRemoteProblem::$providers['luogu']['url'] . '/user/setting?_contentOnly=1');
if ($curl->responseHeaders['Content-Type'] == 'application/json') {
$res = validateLuogu($curl->response);
return true;
}
return false;
}
return false;
} else if ($curl->responseHeaders['Content-Type'] == 'application/json') {
$res = validateLuogu($curl->response);
return true;
}
return false;
}, 3);
die(json_encode(['ok' => $res === true]));
} else if ($type == 'codeforces') {
$curl->setFollowLocation();
$curl->setCookie('JSESSIONID', UOJRequest::post('JSESSIONID', 'is_string', ''));
retry_loop(function () use (&$curl, &$res) {
$curl->get(UOJRemoteProblem::$providers['codeforces']['url'] . '/enter');
if ($curl->error) {
return false;
}
if (str_starts_with($curl->responseHeaders['Content-Type'], 'text/html')) {
if (str_contains($curl->response, 'Login into Codeforces')) {
return false;
}
if (strlen($curl->response) < 1000 && str_contains($curl->response, 'Redirecting...')) {
return false;
}
$res = true;
return true;
}
return false;
}, 3);
} else {
UOJResponse::page406();
}
die(json_encode(['ok' => $res === true]));

View File

@ -0,0 +1,12 @@
<?php
call_user_func(function () { // to prevent variable scope leak
Route::group(
[
'domain' => UOJConfig::$data['web']['main']['host'],
],
function () {
Route::post("/api/remote_judge/custom_account_validator", '/subdomain/api/remote_judge/custom_account_validator.php');
}
);
});

View File

@ -665,7 +665,12 @@ class UOJForm {
EOD;
} else {
echo <<<EOD
if (ok) $("#button-submit-{$this->form_name}").addClass('disabled');
if (ok) {
$("#button-submit-{$this->form_name}").addClass('disabled');
$(this).submit(function () {
return false;
});
}
return ok;
EOD;
}

View File

@ -5,6 +5,7 @@ require $_SERVER['DOCUMENT_ROOT'] . '/app/libs/uoj-lib.php';
require UOJContext::documentRoot().'/app/route.php';
require UOJContext::documentRoot().'/app/controllers/subdomain/blog/route.php';
require UOJContext::documentRoot().'/app/controllers/subdomain/api/route.php';
include UOJContext::documentRoot().'/app/controllers'.call_user_func(function() {
$route = Route::dispatch();

View File

@ -958,19 +958,68 @@ $.fn.remote_submit_type_group = function(oj, pid, url, submit_type) {
var input_submit_type_bot = $('<input class="form-check-input" type="radio" name="answer_remote_submit_type" id="' + input_submit_type_bot_id + '" value="bot" />');
var input_submit_type_my = $('<input class="form-check-input" type="radio" name="answer_remote_submit_type" id="' + input_submit_type_my_id + '" value="my" />');
var input_my_account_data = $('<input type="hidden" name="answer_remote_account_data" value="" />');
var my_account_validation_status = $('<span />').append('<span class="text-secondary">待验证</span>');
var my_account_validation_btn = $('<button type="button" class="btn btn-secondary btn-sm ms-2">验证</button>');
var validate_my_account = function(data) {
my_account_validation_btn.html('<span class="spinner-border spinner-border-sm" role="status"></span>');
my_account_validation_btn.addClass('disabled');
$.ajax({
type: 'POST',
url: '/api/remote_judge/custom_account_validator?type=' + oj,
data: data,
success: function(res) {
my_account_validation_btn.html('验证');
my_account_validation_btn.removeClass('disabled');
console.log('Validation status', res);
if (res.ok) {
my_account_validation_status.html('<span class="text-success">可用</span>');
} else {
my_account_validation_status.html('<span class="text-danger">不可用</span>');
}
},
error: function() {
my_account_validation_btn.html('验证');
my_account_validation_btn.removeClass('disabled');
my_account_validation_status.html('<span class="text-secondary">待验证</span>');
},
dataType: 'json',
});
};
var div_submit_type_bot = $('<div id="' + div_submit_type_bot_id + '" />')
.append('<div class="mt-3">将使用公用账号提交本题。</div>');
var div_submit_type_my = $('<div id="' + div_submit_type_my_id + '" />')
.append('<div class="mt-3">将使用您的账号提交本题。</div>');
.append($('<div class="mt-3" />')
.append('<span>将使用您的账号提交本题。</span>')
.append('<span>账号状态:</span>')
.append(my_account_validation_status)
.append(my_account_validation_btn)
);
if ('localStorage' in window) {
var prefer_submit_type = localStorage.getItem('uoj_remote_judge_save_prefer_submit_type__' + oj) || null;
var save_prefer_submit_type = function(type) {
localStorage.setItem('uoj_remote_judge_save_prefer_submit_type__' + oj, type);
}
} else {
var prefer_submit_type = null;
var save_prefer_submit_type = function(type) {};
}
input_submit_type_bot.click(function() {
div_submit_type_my.hide('fast');
div_submit_type_bot.show('fast');
save_prefer_submit_type('bot');
});
input_submit_type_my.click(function() {
div_submit_type_bot.hide('fast');
div_submit_type_my.show('fast');
save_prefer_submit_type('my');
});
if (submit_type[0] == 'bot') {
@ -983,15 +1032,26 @@ $.fn.remote_submit_type_group = function(oj, pid, url, submit_type) {
if (submit_type.indexOf('bot') == -1) {
input_submit_type_bot.attr('disabled', 'disabled');
} else if (prefer_submit_type == 'bot') {
div_submit_type_my.hide();
div_submit_type_bot.show();
input_submit_type_bot[0].checked = true;
input_submit_type_my[0].checked = false;
}
if (submit_type.indexOf('my') == -1) {
input_submit_type_my.attr('disabled', 'disabled');
} else if (prefer_submit_type == 'my') {
div_submit_type_bot.hide();
div_submit_type_my.show();
input_submit_type_bot[0].checked = false;
input_submit_type_my[0].checked = true;
}
if (oj == 'luogu') {
var luogu_account_data = {"_uid": "", "__client_id": ""};
var input_luogu_uid = $('<input class="form-control" type="text" name="luogu_uid" id="input-luogu_uid" />');
var input_luogu_client_id = $('<input class="form-control" type="text" name="luogu_client_id" id="input-luogu_client_id" />');
var input_luogu_uid = $('<input class="form-control font-monospace" type="text" name="luogu_uid" id="input-luogu_uid" />');
var input_luogu_client_id = $('<input class="form-control font-monospace" type="text" name="luogu_client_id" id="input-luogu_client_id" />');
if ('localStorage' in window) {
try {
@ -1012,32 +1072,50 @@ $.fn.remote_submit_type_group = function(oj, pid, url, submit_type) {
luogu_account_data._uid = $(this).val();
input_my_account_data.val(JSON.stringify(luogu_account_data));
save_luogu_account_data();
my_account_validation_status.html('<span class="text-secondary">待验证</span>');
});
input_luogu_client_id.change(function() {
luogu_account_data.__client_id = $(this).val();
input_my_account_data.val(JSON.stringify(luogu_account_data));
save_luogu_account_data();
my_account_validation_status.html('<span class="text-secondary">待验证</span>');
});
my_account_validation_btn.click(function() {
validate_my_account({
type: 'luogu',
_uid: input_luogu_uid.val(),
__client_id: input_luogu_client_id.val(),
});
});
input_my_account_data.val(JSON.stringify(luogu_account_data));
input_luogu_uid.val(luogu_account_data._uid);
input_luogu_client_id.val(luogu_account_data.__client_id);
if (luogu_account_data._uid && luogu_account_data.__client_id){
validate_my_account({
type: 'luogu',
_uid: luogu_account_data._uid,
__client_id: luogu_account_data.__client_id,
});
}
div_submit_type_my.append(
$('<div class="row mt-3" />')
$('<div class="row mt-3 align-items-center" />')
.append($('<div class="col-sm-2" />').append('<label for="input-luogu_uid" class="col-form-label">_uid</label>'))
.append($('<div class="col-sm-4" />').append(input_luogu_uid))
.append($('<div class="col-sm-6" />').append($('<div class="form-text" />').append('请填入 Cookie 中的 <code>_uid</code>。')))
.append($('<div class="col-sm-6" />').append($('<div class="form-text mt-0" />').append('请填入 Cookie 中的 <code>_uid</code>。')))
).append(
$('<div class="row mt-3" />')
$('<div class="row mt-3 align-items-center" />')
.append($('<div class="col-sm-2" />').append('<label for="input-luogu_client_id" class="col-form-label">__client_id</label>'))
.append($('<div class="col-sm-4" />').append(input_luogu_client_id))
.append($('<div class="col-sm-6" />').append($('<div class="form-text" />').append('请填入 Cookie 中的 <code>__client_id</code>。')))
.append($('<div class="col-sm-6" />').append($('<div class="form-text mt-0" />').append('请填入 Cookie 中的 <code>__client_id</code>。')))
).append(input_my_account_data);
} else if (oj == 'codeforces') {
var codeforces_account_data = {"JSESSIONID": ""};
var input_codeforces_jsessionid = $('<input class="form-control" type="text" name="codeforces_jsessionid" id="input-codeforces_jsessionid" />');
var input_codeforces_jsessionid = $('<input class="form-control font-monospace" type="text" name="codeforces_jsessionid" id="input-codeforces_jsessionid" />');
if ('localStorage' in window) {
try {
@ -1056,16 +1134,31 @@ $.fn.remote_submit_type_group = function(oj, pid, url, submit_type) {
codeforces_account_data.JSESSIONID = $(this).val();
input_my_account_data.val(JSON.stringify(codeforces_account_data));
save_codeforces_account_data();
my_account_validation_status.html('<span class="text-secondary">待验证</span>');
});
my_account_validation_btn.click(function() {
validate_my_account({
type: 'codeforces',
JSESSIONID: input_codeforces_jsessionid.val(),
});
});
input_my_account_data.val(JSON.stringify(codeforces_account_data));
input_codeforces_jsessionid.val(codeforces_account_data.JSESSIONID);
if (codeforces_account_data.JSESSIONID) {
validate_my_account({
type: 'codeforces',
JSESSIONID: codeforces_account_data.JSESSIONID,
});
}
div_submit_type_my.append(
$('<div class="row mt-3" />')
$('<div class="row mt-3 align-items-center" />')
.append($('<div class="col-sm-2" />').append('<label for="input-codeforces_jsessionid" class="col-form-label">JSESSIONID</label>'))
.append($('<div class="col-sm-4" />').append(input_codeforces_jsessionid))
.append($('<div class="col-sm-6" />').append($('<div class="form-text" />').append('请填入 Cookie 中的 <code>JSESSIONID</code>。')))
.append($('<div class="col-sm-6" />').append($('<div class="form-text mt-0" />').append('请填入 Cookie 中的 <code>JSESSIONID</code>。')))
).append(input_my_account_data);
} else if (oj == 'uoj') {
var uoj_account_data = {"UOJSESSID": ""};