mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-24 18:48:40 +00:00
Merge branch 'remotejudge/uoj-custom-account'
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
commit
50f3aaab9a
@ -100,45 +100,60 @@ export default class UOJProvider implements IBasicProvider {
|
||||
}
|
||||
|
||||
static constructFromAccountData(data) {
|
||||
throw new Error('Method not implemented.');
|
||||
return new this({
|
||||
type: 'uoj',
|
||||
cookie: Object.entries(data).map(([key, value]) => `${key}=${value}`),
|
||||
});
|
||||
}
|
||||
|
||||
cookie: string[] = [];
|
||||
csrf: string;
|
||||
|
||||
get(url: string) {
|
||||
logger.debug('get', url);
|
||||
logger.debug('get', url, this.cookie);
|
||||
|
||||
if (!url.includes('//'))
|
||||
url = `${this.account.endpoint || 'https://uoj.ac'}${url}`;
|
||||
|
||||
const req = superagent
|
||||
.get(url)
|
||||
.set('Cookie', this.cookie)
|
||||
.set('User-Agent', USER_AGENT);
|
||||
|
||||
if (this.account.proxy) return req.proxy(this.account.proxy);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
post(url: string) {
|
||||
logger.debug('post', url, this.cookie);
|
||||
|
||||
if (!url.includes('//'))
|
||||
url = `${this.account.endpoint || 'https://uoj.ac'}${url}`;
|
||||
|
||||
const req = superagent
|
||||
.post(url)
|
||||
.set('Cookie', this.cookie)
|
||||
.set('User-Agent', USER_AGENT)
|
||||
.type('form');
|
||||
|
||||
if (this.account.proxy) return req.proxy(this.account.proxy);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
async getCsrfToken(url: string) {
|
||||
const { text: html, header } = await this.get(url);
|
||||
|
||||
if (header['set-cookie']) {
|
||||
this.cookie = header['set-cookie'];
|
||||
}
|
||||
|
||||
let value = /_token *: *"(.+?)"/g.exec(html);
|
||||
if (value) return value[1];
|
||||
|
||||
value = /_token" value="(.+?)"/g.exec(html);
|
||||
|
||||
return value?.[1];
|
||||
}
|
||||
|
||||
@ -150,7 +165,11 @@ export default class UOJProvider implements IBasicProvider {
|
||||
|
||||
async ensureLogin() {
|
||||
if (await this.loggedIn) return true;
|
||||
|
||||
if (!this.account.handle) return false;
|
||||
|
||||
logger.info('retry login');
|
||||
|
||||
const _token = await this.getCsrfToken('/login');
|
||||
const { header, text } = await this.post('/login').send({
|
||||
_token,
|
||||
@ -159,11 +178,14 @@ export default class UOJProvider implements IBasicProvider {
|
||||
// NOTE: you should pass a pre-hashed key!
|
||||
password: this.account.password,
|
||||
});
|
||||
|
||||
if (header['set-cookie'] && this.cookie.length === 1) {
|
||||
header['set-cookie'].push(...this.cookie);
|
||||
this.cookie = header['set-cookie'];
|
||||
}
|
||||
|
||||
if (text === 'ok') return true;
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
@ -175,6 +197,16 @@ export default class UOJProvider implements IBasicProvider {
|
||||
next,
|
||||
end
|
||||
) {
|
||||
if (!(await this.ensureLogin())) {
|
||||
await end({
|
||||
error: true,
|
||||
status: 'Judgment Failed',
|
||||
message: 'Login failed',
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const programType = LANGS_MAP[lang] || LANGS_MAP['C++'];
|
||||
const comment = programType.comment;
|
||||
|
||||
|
@ -97,6 +97,29 @@ if ($type == 'luogu') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}, 3);
|
||||
} else if ($type == 'uoj') {
|
||||
$curl->setFollowLocation();
|
||||
$curl->setCookie('UOJSESSID', UOJRequest::post('UOJSESSID', 'is_string', ''));
|
||||
|
||||
retry_loop(function () use (&$curl, &$res) {
|
||||
$curl->get(UOJRemoteProblem::$providers['uoj']['url'] . '/login');
|
||||
|
||||
if ($curl->error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (str_starts_with($curl->responseHeaders['Content-Type'], 'text/html')) {
|
||||
if (str_contains($curl->response, '<title>登录')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$res = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}, 3);
|
||||
} else {
|
||||
|
@ -35,7 +35,7 @@ class UOJRemoteProblem {
|
||||
'未找到该页面',
|
||||
],
|
||||
'languages' => ['C', 'C++03', 'C++11', 'C++', 'C++17', 'C++20', 'Python3', 'Python2.7', 'Java8', 'Java11', 'Java17', 'Pascal'],
|
||||
'submit_type' => ['bot'],
|
||||
'submit_type' => ['bot', 'my'],
|
||||
],
|
||||
'loj' => [
|
||||
'name' => 'LibreOJ',
|
||||
|
@ -1271,6 +1271,53 @@ $.fn.remote_submit_type_group = function(oj, pid, url, submit_type) {
|
||||
.append($('<div class="col-sm-4" />').append(input_loj_token))
|
||||
.append($('<div class="col-sm-6" />').append($('<div class="form-text mt-0" />').append('请前往 <a href="https://loj.ac" target="_blank">LibreOJ</a> 登录账号,然后输入在控制台中运行 <code>console.log(JSON.parse(localStorage.appState).token)</code> 的输出结果。')))
|
||||
);
|
||||
} else if (oj == 'uoj') {
|
||||
var uoj_account_data = {"UOJSESSID": ""};
|
||||
var input_uoj_uojsessid = $('<input class="form-control font-monospace" type="text" name="uoj_uojsessid" id="input-uoj_uojsessid" />');
|
||||
|
||||
if ('localStorage' in window) {
|
||||
try {
|
||||
var uoj_account_data_str = localStorage.getItem('uoj_remote_judge_uoj_account_data');
|
||||
if (uoj_account_data_str) {
|
||||
uoj_account_data = JSON.parse(uoj_account_data_str);
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
var save_uoj_account_data = function() {
|
||||
localStorage.setItem('uoj_remote_judge_uoj_account_data', JSON.stringify(uoj_account_data));
|
||||
}
|
||||
}
|
||||
|
||||
input_uoj_uojsessid.change(function() {
|
||||
uoj_account_data.UOJSESSID = $(this).val();
|
||||
input_my_account_data.val(JSON.stringify(uoj_account_data));
|
||||
save_uoj_account_data();
|
||||
my_account_validation_status.html('<span class="text-secondary">待验证</span>');
|
||||
});
|
||||
|
||||
my_account_validation_btn.click(function() {
|
||||
validate_my_account({
|
||||
type: 'uoj',
|
||||
UOJSESSID: input_uoj_uojsessid.val(),
|
||||
});
|
||||
});
|
||||
|
||||
input_my_account_data.val(JSON.stringify(uoj_account_data));
|
||||
input_uoj_uojsessid.val(uoj_account_data.UOJSESSID);
|
||||
|
||||
if (uoj_account_data.UOJSESSID) {
|
||||
validate_my_account({
|
||||
type: 'uoj',
|
||||
UOJSESSID: uoj_account_data.UOJSESSID,
|
||||
});
|
||||
}
|
||||
|
||||
div_submit_type_my.append(
|
||||
$('<div class="row mt-3 align-items-center" />')
|
||||
.append($('<div class="col-sm-2" />').append('<label for="input-uoj_uojsessid" class="col-form-label">UOJSESSID</label>'))
|
||||
.append($('<div class="col-sm-4" />').append(input_uoj_uojsessid))
|
||||
.append($('<div class="col-sm-6" />').append($('<div class="form-text mt-0" />').append('请填入 Cookie 中的 <code>UOJSESSID</code>。')))
|
||||
).append(input_my_account_data);
|
||||
}
|
||||
|
||||
$(this).append(
|
||||
|
Loading…
Reference in New Issue
Block a user