mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-24 20:18:45 +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) {
|
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[] = [];
|
cookie: string[] = [];
|
||||||
csrf: string;
|
csrf: string;
|
||||||
|
|
||||||
get(url: string) {
|
get(url: string) {
|
||||||
logger.debug('get', url);
|
logger.debug('get', url, this.cookie);
|
||||||
|
|
||||||
if (!url.includes('//'))
|
if (!url.includes('//'))
|
||||||
url = `${this.account.endpoint || 'https://uoj.ac'}${url}`;
|
url = `${this.account.endpoint || 'https://uoj.ac'}${url}`;
|
||||||
|
|
||||||
const req = superagent
|
const req = superagent
|
||||||
.get(url)
|
.get(url)
|
||||||
.set('Cookie', this.cookie)
|
.set('Cookie', this.cookie)
|
||||||
.set('User-Agent', USER_AGENT);
|
.set('User-Agent', USER_AGENT);
|
||||||
|
|
||||||
if (this.account.proxy) return req.proxy(this.account.proxy);
|
if (this.account.proxy) return req.proxy(this.account.proxy);
|
||||||
|
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
post(url: string) {
|
post(url: string) {
|
||||||
logger.debug('post', url, this.cookie);
|
logger.debug('post', url, this.cookie);
|
||||||
|
|
||||||
if (!url.includes('//'))
|
if (!url.includes('//'))
|
||||||
url = `${this.account.endpoint || 'https://uoj.ac'}${url}`;
|
url = `${this.account.endpoint || 'https://uoj.ac'}${url}`;
|
||||||
|
|
||||||
const req = superagent
|
const req = superagent
|
||||||
.post(url)
|
.post(url)
|
||||||
.set('Cookie', this.cookie)
|
.set('Cookie', this.cookie)
|
||||||
.set('User-Agent', USER_AGENT)
|
.set('User-Agent', USER_AGENT)
|
||||||
.type('form');
|
.type('form');
|
||||||
|
|
||||||
if (this.account.proxy) return req.proxy(this.account.proxy);
|
if (this.account.proxy) return req.proxy(this.account.proxy);
|
||||||
|
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCsrfToken(url: string) {
|
async getCsrfToken(url: string) {
|
||||||
const { text: html, header } = await this.get(url);
|
const { text: html, header } = await this.get(url);
|
||||||
|
|
||||||
if (header['set-cookie']) {
|
if (header['set-cookie']) {
|
||||||
this.cookie = header['set-cookie'];
|
this.cookie = header['set-cookie'];
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = /_token *: *"(.+?)"/g.exec(html);
|
let value = /_token *: *"(.+?)"/g.exec(html);
|
||||||
if (value) return value[1];
|
if (value) return value[1];
|
||||||
|
|
||||||
value = /_token" value="(.+?)"/g.exec(html);
|
value = /_token" value="(.+?)"/g.exec(html);
|
||||||
|
|
||||||
return value?.[1];
|
return value?.[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +165,11 @@ export default class UOJProvider implements IBasicProvider {
|
|||||||
|
|
||||||
async ensureLogin() {
|
async ensureLogin() {
|
||||||
if (await this.loggedIn) return true;
|
if (await this.loggedIn) return true;
|
||||||
|
|
||||||
|
if (!this.account.handle) return false;
|
||||||
|
|
||||||
logger.info('retry login');
|
logger.info('retry login');
|
||||||
|
|
||||||
const _token = await this.getCsrfToken('/login');
|
const _token = await this.getCsrfToken('/login');
|
||||||
const { header, text } = await this.post('/login').send({
|
const { header, text } = await this.post('/login').send({
|
||||||
_token,
|
_token,
|
||||||
@ -159,11 +178,14 @@ export default class UOJProvider implements IBasicProvider {
|
|||||||
// NOTE: you should pass a pre-hashed key!
|
// NOTE: you should pass a pre-hashed key!
|
||||||
password: this.account.password,
|
password: this.account.password,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (header['set-cookie'] && this.cookie.length === 1) {
|
if (header['set-cookie'] && this.cookie.length === 1) {
|
||||||
header['set-cookie'].push(...this.cookie);
|
header['set-cookie'].push(...this.cookie);
|
||||||
this.cookie = header['set-cookie'];
|
this.cookie = header['set-cookie'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text === 'ok') return true;
|
if (text === 'ok') return true;
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,6 +197,16 @@ export default class UOJProvider implements IBasicProvider {
|
|||||||
next,
|
next,
|
||||||
end
|
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 programType = LANGS_MAP[lang] || LANGS_MAP['C++'];
|
||||||
const comment = programType.comment;
|
const comment = programType.comment;
|
||||||
|
|
||||||
|
@ -97,6 +97,29 @@ if ($type == 'luogu') {
|
|||||||
return true;
|
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;
|
return false;
|
||||||
}, 3);
|
}, 3);
|
||||||
} else {
|
} 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'],
|
'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' => [
|
'loj' => [
|
||||||
'name' => 'LibreOJ',
|
'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-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> 的输出结果。')))
|
.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(
|
$(this).append(
|
||||||
|
Loading…
Reference in New Issue
Block a user